diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..85c0fd6 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,12 @@ +# Names should be added to this file like so: +# Name or Organization + +Baidu.com, Inc. + +# Initial version authors: +Qin Zuoyan + +# Partial list of contributors: +Jiang Jinpeng +Yan Shiguang + diff --git a/CHANGES b/CHANGES new file mode 100644 index 0000000..eb8fdaa --- /dev/null +++ b/CHANGES @@ -0,0 +1,4 @@ +2014-05-20 version 1.0.0: + + * Submit version 1.0.0. + diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..7f69a63 --- /dev/null +++ b/INSTALL @@ -0,0 +1,45 @@ +Copyright (c) 2014 Baidu.com, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Baidu Inc. nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- + +Currently, sofa-pbrpc only support x86_64 platform, Linux OS, and GCC. + +1. Modify file './depends.mk' to specify depending libs. + The necessary libs is boost, protobuf, snappy and zlib, please + refer to file './README' for details. +2. Run 'make' to build sofa-pbrpc. + The default optimization level is 'O2'. + To change it, modify the 'OPT' variable in file './Makefile'. +3. Run 'make install' to install sofa-pbrpc. + The default install directory is './output'. + To change it, modify the 'PREFIX' variable in file './Makefile'. + +For any build problem, please contact or +. + diff --git a/LICENSE b/LICENSE index 371da19..665aa01 100644 --- a/LICENSE +++ b/LICENSE @@ -1,27 +1,149 @@ -Copyright (c) 2014, BaiduPS -All rights reserved. +Copyright (c) 2014 Baidu.com, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Baidu Inc. nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +-------------------------------------------------------------------------------- + +Boost - free peer-reviewed portable C++ source libraries +Boost Software License - Version 1.0 - August 17th, 2003 +http://www.boost.org/ + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +-------------------------------------------------------------------------------- + +Protocol Buffers - Google's data interchange format +Copyright 2008 Google Inc. All rights reserved. +http://code.google.com/p/protobuf/ + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. +-------------------------------------------------------------------------------- -* Neither the name of the {organization} nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. +protobuf-zerocopy-compression +Copyright (c) 2013, Johannes Ebke and Peter Waller. All rights reserved. +https://github.com/JohannesEbke/protobuf-zerocopy-compression -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. Redistributions in binary +form must reproduce the above copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other materials provided with +the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +-------------------------------------------------------------------------------- + +LZ4 - Fast LZ compression algorithm +Copyright (C) 2011-2012, Yann Collet. +BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +You can contact the author at : +- LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html +- LZ4 source repository : http://code.google.com/p/lz4/ + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a3a714a --- /dev/null +++ b/Makefile @@ -0,0 +1,96 @@ +# Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. See the AUTHORS file for names of contributors. + +#----------------------------------------------- +# Modify prefix to specify the directory to install sofa-pbrpc. +# +PREFIX=./output +#----------------------------------------------- + +#----------------------------------------------- +# Uncomment exactly one of the lines labelled (A), (B), and (C) below +# to switch between compilation modes. +# +OPT ?= -O2 # (A) Production use (optimized mode) +# OPT ?= -g2 # (B) Debug mode, generate full line-level debugging symbols +# OPT ?= -O2 -g2 # (C) Profiling mode: opt, but generate debugging symbols +#----------------------------------------------- + +#----------------------------------------------- +# !!! Do not change the following lines !!! +#----------------------------------------------- + +include depends.mk + +INC=src/sofa/pbrpc/pbrpc.h src/sofa/pbrpc/closure_helper.h src/sofa/pbrpc/closure.h \ + src/sofa/pbrpc/ext_closure.h src/sofa/pbrpc/common.h src/sofa/pbrpc/rpc_channel.h \ + src/sofa/pbrpc/rpc_client.h src/sofa/pbrpc/rpc_controller.h src/sofa/pbrpc/rpc_error_code.h \ + src/sofa/pbrpc/rpc_option.pb.h src/sofa/pbrpc/rpc_option.proto src/sofa/pbrpc/rpc_server.h \ + src/sofa/pbrpc/string_utils.h src/sofa/pbrpc/mock_test_helper.h src/sofa/pbrpc/atomic.h \ + src/sofa/pbrpc/counter.h src/sofa/pbrpc/thread_group.h src/sofa/pbrpc/timeout_manager.h \ + src/sofa/pbrpc/locks.h src/sofa/pbrpc/mutex_lock.h src/sofa/pbrpc/spin_lock.h \ + src/sofa/pbrpc/fast_lock.h src/sofa/pbrpc/rw_lock.h src/sofa/pbrpc/scoped_locker.h \ + src/sofa/pbrpc/condition_variable.h src/sofa/pbrpc/wait_event.h \ + src/sofa/pbrpc/builtin_service.proto src/sofa/pbrpc/builtin_service.pb.h + +LIB=libsofa-pbrpc.a +LIB_SRC=$(wildcard src/sofa/pbrpc/*.cc) +LIB_OBJ=$(patsubst %.cc,%.o,$(LIB_SRC)) + +BIN=sofa-pbrpc-client +BIN_SRC=$(wildcard src/sofa/pbrpc/http-agent/*.cc) +BIN_OBJ=$(patsubst %.cc,%.o,$(BIN_SRC)) + +#----------------------------------------------- + +CXX=g++ +INCPATH=-Isrc -I$(BOOST_HEADER_DIR) -I$(PROTOBUF_DIR)/include -I$(SNAPPY_DIR)/include -I$(ZLIB_DIR)/include +CXXFLAGS += $(OPT) -pipe -W -Wall -fPIC -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -DHAVE_SNAPPY $(INCPATH) + +LIBRARY=$(PROTOBUF_DIR)/lib/libprotobuf.a $(SNAPPY_DIR)/lib/libsnappy.a +LDFLAGS += -L$(ZLIB_DIR)/lib -lpthread -lrt -lz + +all: build + +.PHONY: check_depends build install clean + +check_depends: + @if [ ! -f "$(BOOST_HEADER_DIR)/boost/smart_ptr.hpp" ]; then echo "ERROR: need boost header"; exit 1; fi + @if [ ! -f "$(PROTOBUF_DIR)/include/google/protobuf/message.h" ]; then echo "ERROR: need protobuf header"; exit 1; fi + @if [ ! -f "$(PROTOBUF_DIR)/lib/libprotobuf.a" ]; then echo "ERROR: need protobuf lib"; exit 1; fi + @if [ ! -f "$(SNAPPY_DIR)/include/snappy.h" ]; then echo "ERROR: need snappy header"; exit 1; fi + @if [ ! -f "$(SNAPPY_DIR)/lib/libsnappy.a" ]; then echo "ERROR: need snappy lib"; exit 1; fi + +clean: + rm -f $(LIB) $(LIB_OBJ) $(BIN) $(BIN_OBJ) + +rebuild: clean all + +$(LIB): $(LIB_OBJ) + ar crs $@ $(LIB_OBJ) + +$(BIN): $(LIB) $(BIN_OBJ) + $(CXX) $(LDFLAGS) $(BIN_OBJ) -o $@ $(LIB) $(LIBRARY) + +%.o: %.cpp + $(CXX) $(CXXFLAGS) -c$< -o $@ + +build: check_depends $(LIB) $(BIN) + @echo + @echo 'Build succeed, run "make install" to install sofa-pbrpc.' + +install: $(LIB) $(BIN) + mkdir -p $(PREFIX)/include/sofa/pbrpc + cp -r $(INC) --target-directory $(PREFIX)/include/sofa/pbrpc/ + mkdir -p $(PREFIX)/include/sofa/pbrpc/smart_ptr + cp src/sofa/pbrpc/smart_ptr/*.hpp $(PREFIX)/include/sofa/pbrpc/smart_ptr + mkdir -p $(PREFIX)/include/sofa/pbrpc/smart_ptr/detail + cp src/sofa/pbrpc/smart_ptr/detail/*.hpp $(PREFIX)/include/sofa/pbrpc/smart_ptr/detail + mkdir -p $(PREFIX)/lib + cp $(LIB) $(PREFIX)/lib/ + mkdir -p $(PREFIX)/bin + cp $(BIN) $(PREFIX)/bin/ + @echo + @echo 'Install succeed, target directory is "'$(PREFIX)'".' + diff --git a/README b/README new file mode 100644 index 0000000..28dc4f4 --- /dev/null +++ b/README @@ -0,0 +1,55 @@ +sofa-pbrpc +---------- +A light-weight RPC implement of protobuf RPC framework. + +Features +-------- +* High performace. +* Easy to use. Refer to sample codes in './sample'. +* Support sync call and async call. Refer to './sample/echo'. +* Support three level (service/method/request) timeout. Refer to './sample/timeout_sample'. +* Support transparent compression. Refer to './sample/compress_sample'. +* Support mock test. Refer to './sample/mock_sample'. +* Support network flow control. +* Support auto connecting and reconnecting. +* Support keep alive time of idle connections. +* Support statistics for profiling. + +Dependings +---------- +The lib depends on boost-1.53.0 (only need header), protobuf-2.4.1, snappy and zlib: + boost - http://www.boost.org/ + protobuf - http://code.google.com/p/protobuf/ + snappy - http://code.google.com/p/snappy/ + zlib - http://zlib.net/ + +ATTENTION: boost header is only needed when compiling the lib, but no need for user code. + +Extrally, './unit-test' and './sample/mock_sample' also depends on gtest: + gtest - http://code.google.com/p/googletest/ + +Build +----- +1, Modify file './depends.mk' to specify depending libs. + The necessary libs is boost, protobuf, snappy and zlib. +2, Run 'make' to build sofa-pbrpc. + The default optimization level is 'O2'. + To change it, modify the 'OPT' variable in file './Makefile'. +3, Run 'make install' to install sofa-pbrpc. + The default install directory is './output'. + To change it, modify the 'PREFIX' variable in file './Makefile'. + +Sample +------ +For sample codes, please refer to './sample' and the wiki: + + +Performance +----------- +For performace details, please refer to the wiki: + + +Support +------- +qinzuoyan01@baidu.com (Qin Zuoyan, qinzuoyan@gmail.com) + diff --git a/README.md b/README.md index 8d697e0..3dadc69 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,49 @@ sofa-pbrpc ========== +A light-weight RPC implement of protobuf RPC framework. + +### Features +* High performace. +* Easy to use. Refer to sample codes in './sample'. +* Support sync call and async call. Refer to './sample/echo'. +* Support three level (service/method/request) timeout. Refer to './sample/timeout_sample'. +* Support transparent compression. Refer to './sample/compress_sample'. +* Support mock test. Refer to './sample/mock_sample'. +* Support network flow control. +* Support auto connecting and reconnecting. +* Support keep alive time of idle connections. +* Support statistics for profiling. + +### Dependings +This lib depends on boost-1.53.0 (only need header), protobuf-2.4.1, snappy and zlib: +* boost - http://www.boost.org/ +* protobuf - http://code.google.com/p/protobuf/ +* snappy - http://code.google.com/p/snappy/ +* zlib - http://zlib.net/ + +Attention: boost header is only needed when compiling the lib, but no need for user code. + +Extrally, './unit-test' and './sample/mock_sample' also depends on gtest: +* gtest - http://code.google.com/p/googletest/ + +### Build +1. Modify the file './depends.mk' to specify depending libs.
+ The necessary libs is boost, protobuf, and snappy. +2. Run 'make' to build sofa-pbrpc.
+ The default optimization level is 'O2'.
+ To change it, modify the 'OPT' variable in file './Makefile'. +3. Run 'make install' to install sofa-pbrpc.
+ The default install directory is './output'.
+ To change it, modify the 'PREFIX' variable in file './Makefile'. + +### Sample +For sample codes, please refer to './sample' and the wiki:
+https://github.com/BaiduPS/sofa-pbrpc/wiki + +### Performance +For performace details, please refer to the wiki:
+https://github.com/BaiduPS/sofa-pbrpc/wiki + +### Support +qinzuoyan01@baidu.com (Qin Zuoyan, qinzuoyan@gmail.com) -sofa-pbrpc diff --git a/TODO b/TODO new file mode 100644 index 0000000..b1d1856 --- /dev/null +++ b/TODO @@ -0,0 +1,16 @@ +Http support +------------ +Support http protocal, then user can call methods through http, e.g., by browser. +Request and response message may be serialized/deserialized in json format. +This will provide better usability. + + +Multi-server load balance +------------------------- +By providing multi-server addresses (statically or dynamically), one client stub +can access services deployed on different servers, with intelligent load balance. + +Cross-language client +--------------------- +Provide rpc client lib in other languages, e.g., java and python. + diff --git a/depends.mk b/depends.mk new file mode 100644 index 0000000..a148178 --- /dev/null +++ b/depends.mk @@ -0,0 +1,55 @@ +################################################################ +## Modified this file to specify depending library path. +## +## Depending libs: +## boost-1.53.0 (only need header) +## protobuf-2.4.1 +## snappy +## zlib +## +################################################################ + +################################################################ +## Boost header directory. +## +## Check file exist: +## $(BOOST_HEADER_DIR)/boost/smart_ptr.hpp +## +#BOOST_HEADER_DIR=/home/users/qinzuoyan01/libs/boost_1_53_0 +BOOST_HEADER_DIR= +################################################################ + +################################################################ +## Protocal Buffers directory containing `include' and `lib'. +## +## Check file exist: +## $(PROTOBUF_DIR)/bin/protoc +## $(PROTOBUF_DIR)/include/google/protobuf/message.h +## $(PROTOBUF_DIR)/lib/libprotobuf.a +## +#PROTOBUF_DIR=/home/users/qinzuoyan01/libs/protobuf-2.4.1/output +PROTOBUF_DIR= +################################################################ + +################################################################ +## Snappy directory containing `include' and `lib'. +## +## Check file exist: +## $(SNAPPY_DIR)/include/snappy.h +## $(SNAPPY_DIR)/lib/libsnappy.a +## +#SNAPPY_DIR=/home/users/qinzuoyan01/libs/snappy-1.1.1/output +SNAPPY_DIR= +################################################################ + +################################################################ +## Zlib directory containing `include' and `lib'. +## +## Check file exist: +## $(ZLIB_DIR)/include/zlib.h +## $(ZLIB_DIR)/lib/libz.* +## +## If zlib is already installed in system path, ignore ZLIB_DIR. +#ZLIB_DIR= +################################################################ + diff --git a/sample/compress_sample/Makefile b/sample/compress_sample/Makefile new file mode 100644 index 0000000..00f7053 --- /dev/null +++ b/sample/compress_sample/Makefile @@ -0,0 +1,77 @@ +# Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. See the AUTHORS file for names of contributors. + +#----------------------------------------------- +## Sofa-pbrpc path containing `include'and `lib'. +## +## Check file exist: +## $(SOFA_PBRPC)/include/sofa/pbrpc/pbrpc.h +## $(SOFA_PBRPC)/lib/libsofa-pbrpc.a +## +SOFA_PBRPC=../../output +#----------------------------------------------- + +#----------------------------------------------- +# Uncomment exactly one of the lines labelled (A), (B), and (C) below +# to switch between compilation modes. +# +OPT ?= -O2 # (A) Production use (optimized mode) +# OPT ?= -g2 # (B) Debug mode, w/ full line-level debugging symbols +# OPT ?= -O2 -g2 # (C) Profiling mode: opt, but w/debugging symbols +#----------------------------------------------- + +#----------------------------------------------- +# !!! Do not change the following lines !!! +#----------------------------------------------- + +include ../../depends.mk + +CXX=g++ +INCPATH=-I. -I$(SOFA_PBRPC)/include -I$(BOOST_HEADER_DIR) -I$(PROTOBUF_DIR)/include \ + -I$(SNAPPY_DIR)/include -I$(ZLIB_DIR)/include +CXXFLAGS += $(OPT) -pipe -W -Wall -fPIC -D_GNU_SOURCE -D__STDC_LIMIT_MACROS $(INCPATH) + +LIBRARY=$(SOFA_PBRPC)/lib/libsofa-pbrpc.a $(PROTOBUF_DIR)/lib/libprotobuf.a $(SNAPPY_DIR)/lib/libsnappy.a +LDFLAGS += -L$(ZLIB_DIR)/lib -lpthread -lrt -lz + +PROTO_SRC=echo_service.proto +PROTO_OBJ=$(patsubst %.proto,%.pb.o,$(PROTO_SRC)) +PROTO_OPTIONS=--proto_path=. --proto_path=$(SOFA_PBRPC)/include --proto_path=$(PROTOBUF_DIR)/include + +BIN=server client + +all: check_depends $(BIN) + +.PHONY: check_depends clean + +check_depends: + @if [ ! -f "$(BOOST_HEADER_DIR)/boost/smart_ptr.hpp" ]; then echo "ERROR: need boost header"; exit 1; fi + @if [ ! -f "$(PROTOBUF_DIR)/include/google/protobuf/message.h" ]; then echo "ERROR: need protobuf header"; exit 1; fi + @if [ ! -f "$(PROTOBUF_DIR)/lib/libprotobuf.a" ]; then echo "ERROR: need protobuf lib"; exit 1; fi + @if [ ! -f "$(PROTOBUF_DIR)/bin/protoc" ]; then echo "ERROR: need protoc binary"; exit 1; fi + @if [ ! -f "$(SNAPPY_DIR)/include/snappy.h" ]; then echo "ERROR: need snappy header"; exit 1; fi + @if [ ! -f "$(SNAPPY_DIR)/lib/libsnappy.a" ]; then echo "ERROR: need snappy lib"; exit 1; fi + @if [ ! -f "$(SOFA_PBRPC)/include/sofa/pbrpc/pbrpc.h" ]; then echo "ERROR: need sofa-pbrpc header"; exit 1; fi + @if [ ! -f "$(SOFA_PBRPC)/lib/libsofa-pbrpc.a" ]; then echo "ERROR: need sofa-pbrpc lib"; exit 1; fi + +clean: + @rm -f $(BIN) *.o *.pb.* + +rebuild: clean all + +server: server.o $(PROTO_OBJ) + $(CXX) $(LDFLAGS) $^ -o $@ $(LIBRARY) + +client: client.o $(PROTO_OBJ) + $(CXX) $(LDFLAGS) $^ -o $@ $(LIBRARY) + +%.pb.o: %.pb.cc + $(CXX) $(CXXFLAGS) -c $< -o $@ + +%.pb.cc: %.proto + $(PROTOBUF_DIR)/bin/protoc $(PROTO_OPTIONS) --cpp_out=. $< + +%.o: %.cc $(PROTO_OBJ) + $(CXX) $(CXXFLAGS) -c $< -o $@ + diff --git a/sample/compress_sample/client.cc b/sample/compress_sample/client.cc new file mode 100644 index 0000000..f918ac9 --- /dev/null +++ b/sample/compress_sample/client.cc @@ -0,0 +1,58 @@ +/*************************************************************************** + * + * Copyright (c) 2013 Baidu.com, Inc. All Rights Reserved + * + * Author: qinzuoyan01@baidu.com (Qin Zuoyan) + * CreateTime: 2013-02-22 + * + * Description: + * + **************************************************************************/ + +#include +#include "echo_service.pb.h" + +int main(int /*argc*/, char** /*argv*/) +{ + SOFA_PBRPC_SET_LOG_LEVEL(NOTICE); + + // Define an rpc client. + sofa::pbrpc::RpcClientOptions client_options; + sofa::pbrpc::RpcClient rpc_client(client_options); + + // Define an rpc channel. + sofa::pbrpc::RpcChannelOptions channel_options; + sofa::pbrpc::RpcChannel rpc_channel(&rpc_client, "127.0.0.1:12321", channel_options); + + // Prepare params. + sofa::pbrpc::RpcController* cntl = new sofa::pbrpc::RpcController(); + //cntl->SetTimeout(3000); + sofa::pbrpc::test::EchoRequest* request = + new sofa::pbrpc::test::EchoRequest(); + request->set_message("Hello from qinzuoyan01"); + sofa::pbrpc::test::EchoResponse* response = + new sofa::pbrpc::test::EchoResponse(); + + // Sync call. + sofa::pbrpc::test::EchoServer_Stub* stub = + new sofa::pbrpc::test::EchoServer_Stub(&rpc_channel); + stub->Echo(cntl, request, response, NULL); + int ret = EXIT_SUCCESS; + if (cntl->Failed()) + { + SLOG(ERROR, "request failed: %s", cntl->ErrorText().c_str()); + ret = EXIT_FAILURE; + } + else + { + SLOG(NOTICE, "request succeed: %s", response->message().c_str()); + } + + delete request; + delete response; + delete cntl; + delete stub; + + return ret; +} +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/sample/compress_sample/echo_service.proto b/sample/compress_sample/echo_service.proto new file mode 100644 index 0000000..7886d13 --- /dev/null +++ b/sample/compress_sample/echo_service.proto @@ -0,0 +1,20 @@ +import "sofa/pbrpc/rpc_option.proto"; + +package sofa.pbrpc.test; + +option cc_generic_services = true; + +message EchoRequest { + required string message = 1; +} + +message EchoResponse { + required string message = 1; +} + +service EchoServer { + rpc Echo(EchoRequest) returns(EchoResponse) { + option (sofa.pbrpc.request_compress_type) = CompressTypeSnappy; + option (sofa.pbrpc.response_compress_type) = CompressTypeSnappy; + } +} diff --git a/sample/compress_sample/server.cc b/sample/compress_sample/server.cc new file mode 100644 index 0000000..bcb6201 --- /dev/null +++ b/sample/compress_sample/server.cc @@ -0,0 +1,72 @@ +/*************************************************************************** + * + * Copyright (c) 2013 Baidu.com, Inc. All Rights Reserved + * + * Author: qinzuoyan01@baidu.com (Qin Zuoyan) + * CreateTime: 2013-02-22 + * + * Description: + * + **************************************************************************/ + +#include +#include +#include +#include "echo_service.pb.h" + +class EchoServerImpl : public sofa::pbrpc::test::EchoServer +{ +public: + EchoServerImpl() {} + virtual ~EchoServerImpl() {} + +private: + virtual void Echo(google::protobuf::RpcController* /*controller*/, + const sofa::pbrpc::test::EchoRequest* request, + sofa::pbrpc::test::EchoResponse* response, + google::protobuf::Closure* done) + { + SLOG(NOTICE, "Echo(): request message: %s", request->message().c_str()); + response->set_message("echo message: " + request->message()); + done->Run(); + } +}; + +volatile bool g_quit = false; + +static void SignalIntHandler(int /* sig */) +{ + g_quit = true; +} + +int main(int /*argc*/, char** /*argv*/) +{ + SOFA_PBRPC_SET_LOG_LEVEL(NOTICE); + + // Define an rpc server. + sofa::pbrpc::RpcServerOptions options; + sofa::pbrpc::RpcServer rpc_server(options); + + // Start rpc server. + if (!rpc_server.Start("0.0.0.0:12321")) { + SLOG(ERROR, "start server failed"); + return EXIT_FAILURE; + } + + sofa::pbrpc::test::EchoServer* echo_service = new EchoServerImpl(); + if (!rpc_server.RegisterService(echo_service)) { + SLOG(ERROR, "export service failed"); + return EXIT_FAILURE; + } + + signal(SIGINT, SignalIntHandler); + signal(SIGTERM, SignalIntHandler); + + while (!g_quit) { + sleep(1); + } + + return EXIT_SUCCESS; +} + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/sample/echo/Makefile b/sample/echo/Makefile new file mode 100644 index 0000000..2c5e7df --- /dev/null +++ b/sample/echo/Makefile @@ -0,0 +1,80 @@ +# Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. See the AUTHORS file for names of contributors. + +#----------------------------------------------- +## Sofa-pbrpc path containing `include'and `lib'. +## +## Check file exist: +## $(SOFA_PBRPC)/include/sofa/pbrpc/pbrpc.h +## $(SOFA_PBRPC)/lib/libsofa-pbrpc.a +## +SOFA_PBRPC=../../output +#----------------------------------------------- + +#----------------------------------------------- +# Uncomment exactly one of the lines labelled (A), (B), and (C) below +# to switch between compilation modes. +# +OPT ?= -O2 # (A) Production use (optimized mode) +# OPT ?= -g2 # (B) Debug mode, w/ full line-level debugging symbols +# OPT ?= -O2 -g2 # (C) Profiling mode: opt, but w/debugging symbols +#----------------------------------------------- + +#----------------------------------------------- +# !!! Do not change the following lines !!! +#----------------------------------------------- + +include ../../depends.mk + +CXX=g++ +INCPATH=-I. -I$(SOFA_PBRPC)/include -I$(BOOST_HEADER_DIR) -I$(PROTOBUF_DIR)/include \ + -I$(SNAPPY_DIR)/include -I$(ZLIB_DIR)/include +CXXFLAGS += $(OPT) -pipe -W -Wall -fPIC -D_GNU_SOURCE -D__STDC_LIMIT_MACROS $(INCPATH) + +LIBRARY=$(SOFA_PBRPC)/lib/libsofa-pbrpc.a $(PROTOBUF_DIR)/lib/libprotobuf.a $(SNAPPY_DIR)/lib/libsnappy.a +LDFLAGS += -L$(ZLIB_DIR)/lib -lpthread -lrt -lz + +PROTO_SRC=echo_service.proto +PROTO_OBJ=$(patsubst %.proto,%.pb.o,$(PROTO_SRC)) +PROTO_OPTIONS=--proto_path=. --proto_path=$(SOFA_PBRPC)/include --proto_path=$(PROTOBUF_DIR)/include + +BIN=server client_sync client_async + +all: check_depends $(BIN) + +.PHONY: check_depends clean + +check_depends: + @if [ ! -f "$(BOOST_HEADER_DIR)/boost/smart_ptr.hpp" ]; then echo "ERROR: need boost header"; exit 1; fi + @if [ ! -f "$(PROTOBUF_DIR)/include/google/protobuf/message.h" ]; then echo "ERROR: need protobuf header"; exit 1; fi + @if [ ! -f "$(PROTOBUF_DIR)/lib/libprotobuf.a" ]; then echo "ERROR: need protobuf lib"; exit 1; fi + @if [ ! -f "$(PROTOBUF_DIR)/bin/protoc" ]; then echo "ERROR: need protoc binary"; exit 1; fi + @if [ ! -f "$(SNAPPY_DIR)/include/snappy.h" ]; then echo "ERROR: need snappy header"; exit 1; fi + @if [ ! -f "$(SNAPPY_DIR)/lib/libsnappy.a" ]; then echo "ERROR: need snappy lib"; exit 1; fi + @if [ ! -f "$(SOFA_PBRPC)/include/sofa/pbrpc/pbrpc.h" ]; then echo "ERROR: need sofa-pbrpc header"; exit 1; fi + @if [ ! -f "$(SOFA_PBRPC)/lib/libsofa-pbrpc.a" ]; then echo "ERROR: need sofa-pbrpc lib"; exit 1; fi + +clean: + @rm -f $(BIN) *.o *.pb.* + +rebuild: clean all + +server: server.o $(PROTO_OBJ) + $(CXX) $(LDFLAGS) $^ -o $@ $(LIBRARY) + +client_sync: client_sync.o $(PROTO_OBJ) + $(CXX) $(LDFLAGS) $^ -o $@ $(LIBRARY) + +client_async: client_async.o $(PROTO_OBJ) + $(CXX) $(LDFLAGS) $^ -o $@ $(LIBRARY) + +%.pb.o: %.pb.cc + $(CXX) $(CXXFLAGS) -c $< -o $@ + +%.pb.cc: %.proto + $(PROTOBUF_DIR)/bin/protoc $(PROTO_OPTIONS) --cpp_out=. $< + +%.o: %.cc $(PROTO_OBJ) + $(CXX) $(CXXFLAGS) -c $< -o $@ + diff --git a/sample/echo/client_async.cc b/sample/echo/client_async.cc new file mode 100644 index 0000000..8da1359 --- /dev/null +++ b/sample/echo/client_async.cc @@ -0,0 +1,76 @@ +/*************************************************************************** + * + * Copyright (c) 2013 Baidu.com, Inc. All Rights Reserved + * + * Author: qinzuoyan01@baidu.com (Qin Zuoyan) + * CreateTime: 2013-02-22 + * + * Description: + * + **************************************************************************/ + +#include +#include +#include "echo_service.pb.h" + +void EchoCallback(sofa::pbrpc::RpcController* cntl, + sofa::pbrpc::test::EchoRequest* request, + sofa::pbrpc::test::EchoResponse* response, + bool* callbacked) +{ + SLOG(NOTICE, "RemoteAddress=%s", cntl->RemoteAddress().c_str()); + SLOG(NOTICE, "IsRequestSent=%s", cntl->IsRequestSent() ? "true" : "false"); + if (cntl->IsRequestSent()) + { + SLOG(NOTICE, "LocalAddress=%s", cntl->LocalAddress().c_str()); + SLOG(NOTICE, "SentBytes=%ld", cntl->SentBytes()); + } + + if (cntl->Failed()) { + SLOG(ERROR, "request failed: %s", cntl->ErrorText().c_str()); + } + else { + SLOG(NOTICE, "request succeed: %s", response->message().c_str()); + } + + delete cntl; + delete request; + delete response; + *callbacked = true; +} + +int main() +{ + SOFA_PBRPC_SET_LOG_LEVEL(NOTICE); + + // Define an rpc server. + sofa::pbrpc::RpcClientOptions client_options; + sofa::pbrpc::RpcClient rpc_client(client_options); + + // Define an rpc channel. + sofa::pbrpc::RpcChannelOptions channel_options; + sofa::pbrpc::RpcChannel rpc_channel(&rpc_client, "127.0.0.1:12321", channel_options); + + // Prepare parameters. + sofa::pbrpc::RpcController* cntl = new sofa::pbrpc::RpcController(); + cntl->SetTimeout(3000); + sofa::pbrpc::test::EchoRequest* request = new sofa::pbrpc::test::EchoRequest(); + request->set_message("Hello from qinzuoyan01"); + sofa::pbrpc::test::EchoResponse* response = new sofa::pbrpc::test::EchoResponse(); + bool callbacked = false; + google::protobuf::Closure* done = sofa::pbrpc::NewClosure( + &EchoCallback, cntl, request, response, &callbacked); + + // Async call. + sofa::pbrpc::test::EchoServer_Stub stub(&rpc_channel); + stub.Echo(cntl, request, response, done); + + // Wait call done. + while (!callbacked) { + usleep(100000); + } + + return EXIT_SUCCESS; +} + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/sample/echo/client_sync.cc b/sample/echo/client_sync.cc new file mode 100644 index 0000000..46393e0 --- /dev/null +++ b/sample/echo/client_sync.cc @@ -0,0 +1,70 @@ +/*************************************************************************** + * + * Copyright (c) 2013 Baidu.com, Inc. All Rights Reserved + * + * Author: qinzuoyan01@baidu.com (Qin Zuoyan) + * CreateTime: 2013-02-22 + * + * Description: + * + **************************************************************************/ + +#include +#include "echo_service.pb.h" + +int main() +{ + SOFA_PBRPC_SET_LOG_LEVEL(NOTICE); + + // Define an rpc client. + sofa::pbrpc::RpcClientOptions client_options; + sofa::pbrpc::RpcClient rpc_client(client_options); + + // Define an rpc channel. + sofa::pbrpc::RpcChannelOptions channel_options; + sofa::pbrpc::RpcChannel rpc_channel(&rpc_client, "127.0.0.1:12321", channel_options); + + // Prepare parameters. + sofa::pbrpc::RpcController* cntl = new sofa::pbrpc::RpcController(); + cntl->SetTimeout(3000); + sofa::pbrpc::test::EchoRequest* request = + new sofa::pbrpc::test::EchoRequest(); + request->set_message("Hello from qinzuoyan01"); + sofa::pbrpc::test::EchoResponse* response = + new sofa::pbrpc::test::EchoResponse(); + + // Sync call. + sofa::pbrpc::test::EchoServer_Stub* stub = + new sofa::pbrpc::test::EchoServer_Stub(&rpc_channel); + stub->Echo(cntl, request, response, NULL); + + // Check if the request has been sent. + // If has been sent, then can get the sent bytes. + SLOG(NOTICE, "RemoteAddress=%s", cntl->RemoteAddress().c_str()); + SLOG(NOTICE, "IsRequestSent=%s", cntl->IsRequestSent() ? "true" : "false"); + if (cntl->IsRequestSent()) + { + SLOG(NOTICE, "LocalAddress=%s", cntl->LocalAddress().c_str()); + SLOG(NOTICE, "SentBytes=%ld", cntl->SentBytes()); + } + + // Check if failed. + if (cntl->Failed()) + { + SLOG(ERROR, "request failed: %s", cntl->ErrorText().c_str()); + } + else + { + SLOG(NOTICE, "request succeed: %s", response->message().c_str()); + } + + // Destroy objects. + delete cntl; + delete request; + delete response; + delete stub; + + return EXIT_SUCCESS; +} + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/sample/echo/echo_service.proto b/sample/echo/echo_service.proto new file mode 100644 index 0000000..637ac32 --- /dev/null +++ b/sample/echo/echo_service.proto @@ -0,0 +1,16 @@ +package sofa.pbrpc.test; + +option cc_generic_services = true; +option java_generic_services = true; + +message EchoRequest { + required string message = 1; +} + +message EchoResponse { + required string message = 1; +} + +service EchoServer { + rpc Echo(EchoRequest) returns(EchoResponse); +} diff --git a/sample/echo/server.cc b/sample/echo/server.cc new file mode 100644 index 0000000..62f4568 --- /dev/null +++ b/sample/echo/server.cc @@ -0,0 +1,86 @@ +/*************************************************************************** + * + * Copyright (c) 2013 Baidu.com, Inc. All Rights Reserved + * + * Author: qinzuoyan01@baidu.com (Qin Zuoyan) + * CreateTime: 2013-02-22 + * + * Description: + * + **************************************************************************/ + +#include +#include +#include +#include "echo_service.pb.h" + +class EchoServerImpl : public sofa::pbrpc::test::EchoServer +{ +public: + EchoServerImpl() {} + virtual ~EchoServerImpl() {} + +private: + virtual void Echo(google::protobuf::RpcController* controller, + const sofa::pbrpc::test::EchoRequest* request, + sofa::pbrpc::test::EchoResponse* response, + google::protobuf::Closure* done) + { + SLOG(NOTICE, "Echo(): request message from %s: %s", + static_cast(controller)->RemoteAddress().c_str(), + request->message().c_str()); + response->set_message("echo message: " + request->message()); + done->Run(); + } +}; + +bool thread_init_func() +{ + sleep(1); + SLOG(INFO, "Init work thread succeed"); + return true; +} + +void thread_dest_func() +{ + SLOG(INFO, "Destroy work thread succeed"); +} + +int main() +{ + SOFA_PBRPC_SET_LOG_LEVEL(NOTICE); + + // Define an rpc server. + sofa::pbrpc::RpcServerOptions options; + options.work_thread_init_func = sofa::pbrpc::NewPermanentExtClosure(&thread_init_func); + options.work_thread_dest_func = sofa::pbrpc::NewPermanentExtClosure(&thread_dest_func); + sofa::pbrpc::RpcServer rpc_server(options); + + // Start rpc server. + if (!rpc_server.Start("0.0.0.0:12321")) { + SLOG(ERROR, "start server failed"); + return EXIT_FAILURE; + } + + // Register service. + sofa::pbrpc::test::EchoServer* echo_service = new EchoServerImpl(); + if (!rpc_server.RegisterService(echo_service)) { + SLOG(ERROR, "export service failed"); + return EXIT_FAILURE; + } + + // Wait signal. + rpc_server.Run(); + + // Stop rpc server. + rpc_server.Stop(); + + // Delete closures. + // Attention: should delete the closures after server stopped, or may be crash. + delete options.work_thread_init_func; + delete options.work_thread_dest_func; + + return EXIT_SUCCESS; +} + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/sample/mock_sample/Makefile b/sample/mock_sample/Makefile new file mode 100644 index 0000000..0052782 --- /dev/null +++ b/sample/mock_sample/Makefile @@ -0,0 +1,80 @@ +# Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. See the AUTHORS file for names of contributors. + +#----------------------------------------------- +## Sofa-pbrpc path containing `include'and `lib'. +## +## Check file exist: +## $(SOFA_PBRPC)/include/sofa/pbrpc/pbrpc.h +## $(SOFA_PBRPC)/lib/libsofa-pbrpc.a +## +SOFA_PBRPC=../../output +#----------------------------------------------- + +#----------------------------------------------- +# Uncomment exactly one of the lines labelled (A), (B), and (C) below +# to switch between compilation modes. +# +OPT ?= -O2 # (A) Production use (optimized mode) +# OPT ?= -g2 # (B) Debug mode, w/ full line-level debugging symbols +# OPT ?= -O2 -g2 # (C) Profiling mode: opt, but w/debugging symbols +#----------------------------------------------- + +#----------------------------------------------- +# !!! Do not change the following lines !!! +#----------------------------------------------- + +include ../../depends.mk +include depends.mk + +CXX=g++ +INCPATH=-I. -I$(SOFA_PBRPC)/include -I$(BOOST_HEADER_DIR) -I$(PROTOBUF_DIR)/include \ + -I$(SNAPPY_DIR)/include -I$(ZLIB_DIR)/include -I$(GTEST_DIR)/include +CXXFLAGS += $(OPT) -pipe -W -Wall -fPIC -D_GNU_SOURCE -D__STDC_LIMIT_MACROS $(INCPATH) + +LIBRARY=$(SOFA_PBRPC)/lib/libsofa-pbrpc.a $(PROTOBUF_DIR)/lib/libprotobuf.a $(SNAPPY_DIR)/lib/libsnappy.a +LDFLAGS += -L$(ZLIB_DIR)/lib -lpthread -lrt -lz + +PROTO_SRC=echo_service.proto +PROTO_OBJ=$(patsubst %.proto,%.pb.o,$(PROTO_SRC)) +PROTO_OPTIONS=--proto_path=. --proto_path=$(SOFA_PBRPC)/include --proto_path=$(PROTOBUF_DIR)/include + +BIN=mock_test_sample + +all: check_depends $(BIN) + +.PHONY: check_depends clean + +check_depends: + @if [ ! -f "$(BOOST_HEADER_DIR)/boost/smart_ptr.hpp" ]; then echo "ERROR: need boost header"; exit 1; fi + @if [ ! -f "$(PROTOBUF_DIR)/include/google/protobuf/message.h" ]; then echo "ERROR: need protobuf header"; exit 1; fi + @if [ ! -f "$(PROTOBUF_DIR)/lib/libprotobuf.a" ]; then echo "ERROR: need protobuf lib"; exit 1; fi + @if [ ! -f "$(PROTOBUF_DIR)/bin/protoc" ]; then echo "ERROR: need protoc binary"; exit 1; fi + @if [ ! -f "$(SNAPPY_DIR)/include/snappy.h" ]; then echo "ERROR: need snappy header"; exit 1; fi + @if [ ! -f "$(SNAPPY_DIR)/lib/libsnappy.a" ]; then echo "ERROR: need snappy lib"; exit 1; fi + @if [ ! -f "$(SOFA_PBRPC)/include/sofa/pbrpc/pbrpc.h" ]; then echo "ERROR: need sofa-pbrpc header"; exit 1; fi + @if [ ! -f "$(SOFA_PBRPC)/lib/libsofa-pbrpc.a" ]; then echo "ERROR: need sofa-pbrpc lib"; exit 1; fi + @if [ ! -f "$(GTEST_DIR)/src/gtest-all.cc" ]; then echo "ERROR: need gtest"; exit 1; fi + +clean: + @rm -f $(BIN) *.o *.pb.* libgtest.a + +rebuild: clean all + +mock_test_sample: mock_test_sample.o $(PROTO_OBJ) libgtest.a + $(CXX) $(LDFLAGS) $^ -o $@ $(LIBRARY) libgtest.a + +%.pb.o: %.pb.cc + $(CXX) $(CXXFLAGS) -c $< -o $@ + +%.pb.cc: %.proto + $(PROTOBUF_DIR)/bin/protoc $(PROTO_OPTIONS) --cpp_out=. $< + +%.o: %.cc $(PROTO_OBJ) + $(CXX) $(CXXFLAGS) -c $< -o $@ + +libgtest.a: + g++ -isystem $(GTEST_DIR)/include -I$(GTEST_DIR) -pthread -c $(GTEST_DIR)/src/gtest-all.cc + ar -rv libgtest.a gtest-all.o + diff --git a/sample/mock_sample/depends.mk b/sample/mock_sample/depends.mk new file mode 100644 index 0000000..ce597b9 --- /dev/null +++ b/sample/mock_sample/depends.mk @@ -0,0 +1,18 @@ +############################################################### +## Modified this file to specify your library path. +## +## Depending libs: +## gtest-1.7.0 +## +############################################################### + +############################################################### +## Google Test directory. +## +## Check file exist: +## $(GTEST_DIR)/src/gtest-all.cc +## +#GTEST_DIR=/home/users/qinzuoyan01/libs/gtest-1.7.0 +GTEST_DIR= +############################################################### + diff --git a/sample/mock_sample/echo_service.proto b/sample/mock_sample/echo_service.proto new file mode 100644 index 0000000..9117a9d --- /dev/null +++ b/sample/mock_sample/echo_service.proto @@ -0,0 +1,15 @@ +package sofa.pbrpc.test; + +option cc_generic_services = true; + +message EchoRequest { + required string message = 1; +} + +message EchoResponse { + required string message = 1; +} + +service EchoServer { + rpc Echo(EchoRequest) returns(EchoResponse); +} diff --git a/sample/mock_sample/mock_test_sample.cc b/sample/mock_sample/mock_test_sample.cc new file mode 100644 index 0000000..286f515 --- /dev/null +++ b/sample/mock_sample/mock_test_sample.cc @@ -0,0 +1,178 @@ +/*************************************************************************** + * + * Copyright (c) 2013 Baidu.com, Inc. All Rights Reserved + * + * Author: qinzuoyan01@baidu.com (Qin Zuoyan) + * CreateTime: 2013-04-03 + * + * Description: + * + **************************************************************************/ + +#include +#include +#include +#include +#include "echo_service.pb.h" + +using namespace ::sofa::pbrpc; +using namespace ::sofa::pbrpc::test; + +void MockEchoSuccess(::google::protobuf::RpcController* /*controller*/, + const ::google::protobuf::Message* request, + ::google::protobuf::Message* response, + ::google::protobuf::Closure* done) +{ + SLOG(NOTICE, "MockEchoSuccess() called"); + ((EchoResponse*)response)->set_message(((EchoRequest*)request)->message()); + done->Run(); +} + +void MockEchoFail(::google::protobuf::RpcController* controller, + const ::google::protobuf::Message* /*request*/, + ::google::protobuf::Message* /*response*/, + ::google::protobuf::Closure* done) +{ + SLOG(NOTICE, "MockEchoFail() called"); + controller->SetFailed("mock failed"); + done->Run(); +} + +class MockTest : public ::testing::Test +{ +protected: + MockTest() {} + virtual ~MockTest() {} + virtual void SetUp() { + SOFA_PBRPC_SET_LOG_LEVEL(NOTICE); + + // enable mock and register mock method + SOFA_PBRPC_ENABLE_MOCK(); + + _rpc_client = new RpcClient(); + } + virtual void TearDown() { + delete _rpc_client; + } + + RpcClient* _rpc_client; +}; + +TEST_F(MockTest, test_registered_mock_sync_success) +{ + SOFA_PBRPC_CLEAR_MOCK_METHOD(); + SOFA_PBRPC_REGISTER_MOCK_METHOD("sofa.pbrpc.test.EchoServer.Echo", + NewPermanentExtClosure(&MockEchoSuccess)); + + RpcChannel mock_channel(_rpc_client, SOFA_PBRPC_MOCK_CHANNEL_ADDRESS_PREFIX + std::string("a:0")); + EchoServer_Stub* stub = new EchoServer_Stub(&mock_channel); + RpcController* cntl = new sofa::pbrpc::RpcController(); + EchoRequest* request = new EchoRequest(); + request->set_message("Hello from qinzuoyan01"); + EchoResponse* response = new EchoResponse(); + + stub->Echo(cntl, request, response, NULL); + + SLOG(NOTICE, "ErrorText: %s", cntl->ErrorText().c_str()); + ASSERT_FALSE(cntl->Failed()); + ASSERT_TRUE(cntl->IsRequestSent()); + ASSERT_GT(cntl->SentBytes(), 0); + ASSERT_EQ("Hello from qinzuoyan01", response->message()); + + delete request; + delete response; + delete cntl; + delete stub; +} + +TEST_F(MockTest, test_registered_mock_sync_fail) +{ + SOFA_PBRPC_CLEAR_MOCK_METHOD(); + SOFA_PBRPC_REGISTER_MOCK_METHOD("sofa.pbrpc.test.EchoServer.Echo", + NewPermanentExtClosure(&MockEchoFail)); + + RpcChannel mock_channel(_rpc_client, SOFA_PBRPC_MOCK_CHANNEL_ADDRESS_PREFIX + std::string("a:0")); + EchoServer_Stub* stub = new EchoServer_Stub(&mock_channel); + RpcController* cntl = new sofa::pbrpc::RpcController(); + EchoRequest* request = new EchoRequest(); + request->set_message("Hello from qinzuoyan01"); + EchoResponse* response = new EchoResponse(); + + stub->Echo(cntl, request, response, NULL); + ASSERT_TRUE(cntl->Failed()); + ASSERT_FALSE(cntl->IsRequestSent()); + ASSERT_EQ(RPC_ERROR_FROM_USER, cntl->ErrorCode()); + ASSERT_EQ("RPC_ERROR_FROM_USER: mock failed", cntl->ErrorText()); + + delete request; + delete response; + delete cntl; + delete stub; +} + +void EchoCallback(sofa::pbrpc::RpcController* cntl, bool* callbacked) +{ + SLOG(NOTICE, "EchoCallback(): %s", cntl->ErrorText().c_str()); + ASSERT_TRUE(cntl->Failed()); + ASSERT_EQ(RPC_ERROR_FROM_USER, cntl->ErrorCode()); + ASSERT_EQ("RPC_ERROR_FROM_USER: mock failed", cntl->ErrorText()); + *callbacked = true; +} +TEST_F(MockTest, test_registered_mock_async_fail) +{ + SOFA_PBRPC_CLEAR_MOCK_METHOD(); + SOFA_PBRPC_REGISTER_MOCK_METHOD("sofa.pbrpc.test.EchoServer.Echo", + NewPermanentExtClosure(&MockEchoFail)); + + RpcChannel mock_channel(_rpc_client, SOFA_PBRPC_MOCK_CHANNEL_ADDRESS_PREFIX + std::string("a:0")); + EchoServer_Stub* stub = new EchoServer_Stub(&mock_channel); + RpcController* cntl = new sofa::pbrpc::RpcController(); + EchoRequest* request = new EchoRequest(); + request->set_message("Hello from qinzuoyan01"); + EchoResponse* response = new EchoResponse(); + bool callbacked = false; + google::protobuf::Closure* done = NewClosure(&EchoCallback, cntl, &callbacked); + + stub->Echo(cntl, request, response, done); + while (!callbacked) { + usleep(10); + } + ASSERT_TRUE(cntl->Failed()); + ASSERT_EQ(RPC_ERROR_FROM_USER, cntl->ErrorCode()); + ASSERT_EQ("RPC_ERROR_FROM_USER: mock failed", cntl->ErrorText()); + + delete request; + delete response; + delete cntl; + delete stub; +} + +TEST_F(MockTest, test_unregistered_method) +{ + SOFA_PBRPC_CLEAR_MOCK_METHOD(); + + RpcChannel mock_channel(_rpc_client, SOFA_PBRPC_MOCK_CHANNEL_ADDRESS_PREFIX + std::string("a:0")); + EchoServer_Stub* stub = new EchoServer_Stub(&mock_channel); + RpcController* cntl = new sofa::pbrpc::RpcController(); + EchoRequest* request = new EchoRequest(); + request->set_message("Hello from qinzuoyan01"); + EchoResponse* response = new EchoResponse(); + + stub->Echo(cntl, request, response, NULL); + ASSERT_TRUE(cntl->Failed()); + ASSERT_EQ(RPC_ERROR_FOUND_METHOD, cntl->ErrorCode()); + ASSERT_EQ("RPC_ERROR_FOUND_METHOD: mock method not registered: sofa.pbrpc.test.EchoServer.Echo", cntl->ErrorText()); + + delete request; + delete response; + delete cntl; + delete stub; +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/sample/timeout_sample/Makefile b/sample/timeout_sample/Makefile new file mode 100644 index 0000000..eb3008f --- /dev/null +++ b/sample/timeout_sample/Makefile @@ -0,0 +1,77 @@ +# Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. See the AUTHORS file for names of contributors. + +#----------------------------------------------- +## Sofa-pbrpc path containing `include'and `lib'. +## +## Check file exist: +## $(SOFA_PBRPC)/include/sofa/pbrpc/pbrpc.h +## $(SOFA_PBRPC)/lib/libsofa-pbrpc.a +## +SOFA_PBRPC=../../output +#----------------------------------------------- + +#----------------------------------------------- +# Uncomment exactly one of the lines labelled (A), (B), and (C) below +# to switch between compilation modes. +# +OPT ?= -O2 # (A) Production use (optimized mode) +# OPT ?= -g2 # (B) Debug mode, w/ full line-level debugging symbols +# OPT ?= -O2 -g2 # (C) Profiling mode: opt, but w/debugging symbols +#----------------------------------------------- + +#----------------------------------------------- +# !!! Do not change the following lines !!! +#----------------------------------------------- + +include ../../depends.mk + +CXX=g++ +INCPATH=-I. -I$(SOFA_PBRPC)/include -I$(BOOST_HEADER_DIR) -I$(PROTOBUF_DIR)/include \ + -I$(SNAPPY_DIR)/include -I$(ZLIB_DIR)/include +CXXFLAGS += $(OPT) -pipe -W -Wall -fPIC -D_GNU_SOURCE -D__STDC_LIMIT_MACROS $(INCPATH) + +LIBRARY=$(SOFA_PBRPC)/lib/libsofa-pbrpc.a $(PROTOBUF_DIR)/lib/libprotobuf.a $(SNAPPY_DIR)/lib/libsnappy.a +LDFLAGS += -L$(ZLIB_DIR)/lib -lpthread -lrt -lz + +PROTO_SRC=sleep_service.proto +PROTO_OBJ=$(patsubst %.proto,%.pb.o,$(PROTO_SRC)) +PROTO_OPTIONS=--proto_path=. --proto_path=$(SOFA_PBRPC)/include --proto_path=$(PROTOBUF_DIR)/include + +BIN=server client + +all: check_depends $(BIN) + +.PHONY: check_depends clean + +check_depends: + @if [ ! -f "$(BOOST_HEADER_DIR)/boost/smart_ptr.hpp" ]; then echo "ERROR: need boost header"; exit 1; fi + @if [ ! -f "$(PROTOBUF_DIR)/include/google/protobuf/message.h" ]; then echo "ERROR: need protobuf header"; exit 1; fi + @if [ ! -f "$(PROTOBUF_DIR)/lib/libprotobuf.a" ]; then echo "ERROR: need protobuf lib"; exit 1; fi + @if [ ! -f "$(PROTOBUF_DIR)/bin/protoc" ]; then echo "ERROR: need protoc binary"; exit 1; fi + @if [ ! -f "$(SNAPPY_DIR)/include/snappy.h" ]; then echo "ERROR: need snappy header"; exit 1; fi + @if [ ! -f "$(SNAPPY_DIR)/lib/libsnappy.a" ]; then echo "ERROR: need snappy lib"; exit 1; fi + @if [ ! -f "$(SOFA_PBRPC)/include/sofa/pbrpc/pbrpc.h" ]; then echo "ERROR: need sofa-pbrpc header"; exit 1; fi + @if [ ! -f "$(SOFA_PBRPC)/lib/libsofa-pbrpc.a" ]; then echo "ERROR: need sofa-pbrpc lib"; exit 1; fi + +clean: + @rm -f $(BIN) *.o *.pb.* + +rebuild: clean all + +server: server.o $(PROTO_OBJ) + $(CXX) $(LDFLAGS) $^ -o $@ $(LIBRARY) + +client: client.o $(PROTO_OBJ) + $(CXX) $(LDFLAGS) $^ -o $@ $(LIBRARY) + +%.pb.o: %.pb.cc + $(CXX) $(CXXFLAGS) -c $< -o $@ + +%.pb.cc: %.proto + $(PROTOBUF_DIR)/bin/protoc $(PROTO_OPTIONS) --cpp_out=. $< + +%.o: %.cc $(PROTO_OBJ) + $(CXX) $(CXXFLAGS) -c $< -o $@ + diff --git a/sample/timeout_sample/client.cc b/sample/timeout_sample/client.cc new file mode 100644 index 0000000..ae1b7a2 --- /dev/null +++ b/sample/timeout_sample/client.cc @@ -0,0 +1,119 @@ +/*************************************************************************** + * + * Copyright (c) 2013 Baidu.com, Inc. All Rights Reserved + * + * Author: qinzuoyan01@baidu.com (Qin Zuoyan) + * CreateTime: 2013-02-22 + * + * Description: + * + **************************************************************************/ + +#include +#include "sleep_service.pb.h" + +int main(int /*argc*/, char** /*argv*/) +{ + SOFA_PBRPC_SET_LOG_LEVEL(NOTICE); + + // Define an rpc client. + sofa::pbrpc::RpcClientOptions client_options; + sofa::pbrpc::RpcClient rpc_client(client_options); + + // Define an rpc channel. + sofa::pbrpc::RpcChannelOptions channel_options; + sofa::pbrpc::RpcChannel rpc_channel(&rpc_client, "127.0.0.1:12321", channel_options); + + // Prepare objects. + sofa::pbrpc::RpcController* cntl = new sofa::pbrpc::RpcController(); + sofa::pbrpc::test::SleepRequest* request = + new sofa::pbrpc::test::SleepRequest(); + sofa::pbrpc::test::SleepResponse* response = + new sofa::pbrpc::test::SleepResponse(); + sofa::pbrpc::test::SleepServer_Stub* stub = + new sofa::pbrpc::test::SleepServer_Stub(&rpc_channel); + + // Call 1 + SLOG(NOTICE, "----------- Call 1 ---------------------------------------"); + SLOG(NOTICE, "Sync call SleepWithServiceTimeout(), timeout is 2 seconds."); + SLOG(NOTICE, "Sleep for 1 seconds."); + cntl->Reset(); + request->set_sleep_time(1); + stub->SleepWithServiceTimeout(cntl, request, response, NULL); + SLOG(NOTICE, "Actual timeout is %lld milli-seconds.", cntl->Timeout()); + if (cntl->Failed()) { + SLOG(ERROR, "Failed: %s", cntl->ErrorText().c_str()); + } + else { + SLOG(NOTICE, "Succeed: %s", response->message().c_str()); + } + + // Call 2 + SLOG(NOTICE, "----------- Call 2 ---------------------------------------"); + SLOG(NOTICE, "Sync call SleepWithServiceTimeout(), timeout is 2 seconds."); + SLOG(NOTICE, "Sleep for 3 seconds."); + cntl->Reset(); + request->set_sleep_time(3); + stub->SleepWithServiceTimeout(cntl, request, response, NULL); + SLOG(NOTICE, "Actual timeout is %lld milli-seconds.", cntl->Timeout()); + if (cntl->Failed()) { + SLOG(ERROR, "Failed: %s", cntl->ErrorText().c_str()); + } + else { + SLOG(NOTICE, "Succeed: %s", response->message().c_str()); + } + + // Call 3 + SLOG(NOTICE, "----------- Call 3 ---------------------------------------"); + SLOG(NOTICE, "Sync call SleepWithMethodTimeout(), timeout is 4 seconds."); + SLOG(NOTICE, "Sleep for 3 seconds."); + cntl->Reset(); + request->set_sleep_time(3); + stub->SleepWithMethodTimeout(cntl, request, response, NULL); + SLOG(NOTICE, "Actual timeout is %lld milli-seconds.", cntl->Timeout()); + if (cntl->Failed()) { + SLOG(ERROR, "Failed: %s", cntl->ErrorText().c_str()); + } + else { + SLOG(NOTICE, "Succeed: %s", response->message().c_str()); + } + + // Call 4 + SLOG(NOTICE, "----------- Call 4 ---------------------------------------"); + SLOG(NOTICE, "Sync call SleepWithMethodTimeout(), timeout is 4 seconds."); + SLOG(NOTICE, "Sleep for 5 seconds."); + cntl->Reset(); + request->set_sleep_time(5); + stub->SleepWithMethodTimeout(cntl, request, response, NULL); + SLOG(NOTICE, "Actual timeout is %lld milli-seconds.", cntl->Timeout()); + if (cntl->Failed()) { + SLOG(ERROR, "Failed: %s", cntl->ErrorText().c_str()); + } + else { + SLOG(NOTICE, "Succeed: %s", response->message().c_str()); + } + + // Call 5 + SLOG(NOTICE, "----------- Call 5 ---------------------------------------"); + SLOG(NOTICE, "Sync call SleepWithMethodTimeout(), timeout is 4 seconds."); + SLOG(NOTICE, "Set timeout of RpcController to 1 seconds."); + SLOG(NOTICE, "Sleep for 3 seconds."); + cntl->Reset(); + cntl->SetTimeout(1000); + request->set_sleep_time(3); + stub->SleepWithMethodTimeout(cntl, request, response, NULL); + SLOG(NOTICE, "Actual timeout is %lld milli-seconds.", cntl->Timeout()); + if (cntl->Failed()) { + SLOG(ERROR, "Failed: %s", cntl->ErrorText().c_str()); + } + else { + SLOG(NOTICE, "Succeed: %s", response->message().c_str()); + } + + delete cntl; + delete request; + delete response; + delete stub; + return EXIT_SUCCESS; +} +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/sample/timeout_sample/server.cc b/sample/timeout_sample/server.cc new file mode 100644 index 0000000..f02966d --- /dev/null +++ b/sample/timeout_sample/server.cc @@ -0,0 +1,96 @@ +/*************************************************************************** + * + * Copyright (c) 2013 Baidu.com, Inc. All Rights Reserved + * + * Author: qinzuoyan01@baidu.com (Qin Zuoyan) + * CreateTime: 2013-02-22 + * + * Description: + * + **************************************************************************/ + +#include +#include +#include +#include +#include "sleep_service.pb.h" + +class SleepServerImpl : public sofa::pbrpc::test::SleepServer +{ +public: + SleepServerImpl() {} + virtual ~SleepServerImpl() {} + + virtual void SleepWithServiceTimeout(google::protobuf::RpcController* controller, + const sofa::pbrpc::test::SleepRequest* request, + sofa::pbrpc::test::SleepResponse* response, + google::protobuf::Closure* done) + { + SLOG(NOTICE, "SleepWithServiceTimeout(): request sleep time: %d", request->sleep_time()); + Sleep(controller, request, response, done); + } + + virtual void SleepWithMethodTimeout(google::protobuf::RpcController* controller, + const sofa::pbrpc::test::SleepRequest* request, + sofa::pbrpc::test::SleepResponse* response, + google::protobuf::Closure* done) + { + SLOG(NOTICE, "SleepWithMethodTimeout(): request sleep time: %d", request->sleep_time()); + Sleep(controller, request, response, done); + } + + +private: + void Sleep(google::protobuf::RpcController* controller, + const sofa::pbrpc::test::SleepRequest* request, + sofa::pbrpc::test::SleepResponse* response, + google::protobuf::Closure* done) + { + if (controller->IsCanceled()) + done->Run(); + sleep(request->sleep_time()); + char tmp[100]; + sprintf(tmp, "sleep succeed for %d seconds", request->sleep_time()); + response->set_message(tmp); + done->Run(); + } +}; + +volatile bool g_quit = false; + +static void SignalIntHandler(int /* sig */) +{ + g_quit = true; +} + +int main(int /*argc*/, char** /*argv*/) +{ + SOFA_PBRPC_SET_LOG_LEVEL(NOTICE); + + // Define an rpc server. + sofa::pbrpc::RpcServerOptions options; + sofa::pbrpc::RpcServer rpc_server(options); + + // Start rpc server. + if (!rpc_server.Start("0.0.0.0:12321")) { + SLOG(ERROR, "start server failed"); + return EXIT_FAILURE; + } + + sofa::pbrpc::test::SleepServer* sleep_service = new SleepServerImpl(); + if (!rpc_server.RegisterService(sleep_service)) { + SLOG(ERROR, "export service failed"); + return EXIT_FAILURE; + } + + signal(SIGINT, SignalIntHandler); + signal(SIGTERM, SignalIntHandler); + + while (!g_quit) { + sleep(1); + } + + return EXIT_SUCCESS; +} + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/sample/timeout_sample/sleep_service.proto b/sample/timeout_sample/sleep_service.proto new file mode 100644 index 0000000..488226c --- /dev/null +++ b/sample/timeout_sample/sleep_service.proto @@ -0,0 +1,25 @@ +import "sofa/pbrpc/rpc_option.proto"; + +package sofa.pbrpc.test; + +option cc_generic_services = true; + +message SleepRequest { + required int32 sleep_time = 1; // in seconds +} + +message SleepResponse { + required string message = 1; +} + +service SleepServer { + // The service timeout is 2 seconds. + option (sofa.pbrpc.service_timeout) = 2000; + + rpc SleepWithServiceTimeout(SleepRequest) returns(SleepResponse); + + // The method timeout is 4 seconds. + rpc SleepWithMethodTimeout(SleepRequest) returns(SleepResponse) { + option (sofa.pbrpc.method_timeout) = 4000; + } +} diff --git a/src/compile_proto.sh b/src/compile_proto.sh new file mode 100644 index 0000000..1d770bd --- /dev/null +++ b/src/compile_proto.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +PROTOC=$PROTOBUF_DIR/bin/protoc + +$PROTOC --proto_path=. --cpp_out=. sofa/pbrpc/rpc_meta.proto sofa/pbrpc/rpc_option.proto sofa/pbrpc/builtin_service.proto + diff --git a/src/sofa/pbrpc/ascii.h b/src/sofa/pbrpc/ascii.h new file mode 100644 index 0000000..30b2d31 --- /dev/null +++ b/src/sofa/pbrpc/ascii.h @@ -0,0 +1,297 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_ASCII_H_ +#define _SOFA_PBRPC_ASCII_H_ + +#include +#include + +namespace sofa { +namespace pbrpc { + +struct Ascii +{ +private: + Ascii(); + ~Ascii(); +private: + enum CharTypeMask + { + kUpper = 1 << 0, + kLower = 1 << 1, + kDigit = 1 << 2, + kHexDigit = 1 << 3, + kBlank = 1 << 4, + kSpace = 1 << 5, + kControl = 1 << 6, + kPunct = 1 << 7, + kPrint = 1 << 8, + kGraph = 1 << 9, + }; +public: + static bool IsValid(char c) + { + return (c & 0x80) == 0; + } + + static inline bool IsLower(char c) + { + return CharIncludeAnyTypeMask(c, kLower); + } + + static inline bool IsUpper(char c) + { + return CharIncludeAnyTypeMask(c, kUpper); + } + + static bool IsAlpha(char c) + { + return CharIncludeAnyTypeMask(c, kUpper | kLower); + } + + static bool IsDigit(char c) + { + return CharIncludeAnyTypeMask(c, kDigit); + } + + static bool IsAlphaNumber(char c) + { + return CharIncludeAnyTypeMask(c, kUpper | kLower | kDigit); + } + + static bool IsBlank(char c) + { + return CharIncludeAnyTypeMask(c, kBlank); + } + + static inline bool IsSpace(char c) + { + return CharIncludeAnyTypeMask(c, kSpace); + } + + static bool IsControl(char c) + { + return CharIncludeAnyTypeMask(c, kControl); + } + + static inline bool IsPunct(char c) + { + return CharIncludeAnyTypeMask(c, kPunct); + } + + static inline bool IsHexDigit(char c) + { + return CharIncludeAnyTypeMask(c, kHexDigit); + } + + static inline bool IsGraph(char c) + { + return CharIncludeAnyTypeMask(c, kGraph); + } + + static inline bool IsPrint(char c) + { + return CharIncludeAnyTypeMask(c, kPrint); + } + + static inline char ToAscii(char c) + { + return c & 0x7F; + } + + static inline char ToLower(char c) + { + return IsUpper(c) ? c + ('a' - 'A') : c; + } + + static inline char ToUpper(char c) + { + return IsLower(c) ? c - ('a' - 'A') : c; + } + +private: + static inline int GetCharTypeMask(char c) + { + // This table is generate by the following code: + // + // #include + // #include + // + // int main() + // { + // for (int i = 0; i < 128; ++i) + // { + // printf(" /* 0x%02x(%c) */ ", i, isgraph(i) ? i : ' '); + // if (isblank(i)) printf("kBlank | "); + // if (isspace(i)) printf("kSpace | "); + // if (isupper(i)) printf("kUpper | "); + // if (islower(i)) printf("kLower | "); + // if (isdigit(i)) printf("kDigit | "); + // if (isxdigit(i)) printf("kHexDigit | "); + // if (ispunct(i)) printf("kPunct | "); + // if (iscntrl(i)) printf("kControl | "); + // if (isgraph(i)) printf("kGraph | "); + // if (isprint(i)) printf("kPrint | "); + // printf("0,\n"); + // } + // } + // + // Run as: + // $ LC_ALL=C ./a.out + // + static const uint16_t table[UCHAR_MAX + 1] = + { + /* 0x00( ) */ kControl | 0, + /* 0x01( ) */ kControl | 0, + /* 0x02( ) */ kControl | 0, + /* 0x03( ) */ kControl | 0, + /* 0x04( ) */ kControl | 0, + /* 0x05( ) */ kControl | 0, + /* 0x06( ) */ kControl | 0, + /* 0x07( ) */ kControl | 0, + /* 0x08( ) */ kControl | 0, + /* 0x09( ) */ kBlank | kSpace | kControl | 0, + /* 0x0a( ) */ kSpace | kControl | 0, + /* 0x0b( ) */ kSpace | kControl | 0, + /* 0x0c( ) */ kSpace | kControl | 0, + /* 0x0d( ) */ kSpace | kControl | 0, + /* 0x0e( ) */ kControl | 0, + /* 0x0f( ) */ kControl | 0, + /* 0x10( ) */ kControl | 0, + /* 0x11( ) */ kControl | 0, + /* 0x12( ) */ kControl | 0, + /* 0x13( ) */ kControl | 0, + /* 0x14( ) */ kControl | 0, + /* 0x15( ) */ kControl | 0, + /* 0x16( ) */ kControl | 0, + /* 0x17( ) */ kControl | 0, + /* 0x18( ) */ kControl | 0, + /* 0x19( ) */ kControl | 0, + /* 0x1a( ) */ kControl | 0, + /* 0x1b( ) */ kControl | 0, + /* 0x1c( ) */ kControl | 0, + /* 0x1d( ) */ kControl | 0, + /* 0x1e( ) */ kControl | 0, + /* 0x1f( ) */ kControl | 0, + /* 0x20( ) */ kBlank | kSpace | kPrint | 0, + /* 0x21(!) */ kPunct | kGraph | kPrint | 0, + /* 0x22(") */ kPunct | kGraph | kPrint | 0, + /* 0x23(#) */ kPunct | kGraph | kPrint | 0, + /* 0x24($) */ kPunct | kGraph | kPrint | 0, + /* 0x25(%) */ kPunct | kGraph | kPrint | 0, + /* 0x26(&) */ kPunct | kGraph | kPrint | 0, + /* 0x27(') */ kPunct | kGraph | kPrint | 0, + /* 0x28(() */ kPunct | kGraph | kPrint | 0, + /* 0x29()) */ kPunct | kGraph | kPrint | 0, + /* 0x2a(*) */ kPunct | kGraph | kPrint | 0, + /* 0x2b(+) */ kPunct | kGraph | kPrint | 0, + /* 0x2c(,) */ kPunct | kGraph | kPrint | 0, + /* 0x2d(-) */ kPunct | kGraph | kPrint | 0, + /* 0x2e(.) */ kPunct | kGraph | kPrint | 0, + /* 0x2f(/) */ kPunct | kGraph | kPrint | 0, + /* 0x30(0) */ kDigit | kHexDigit | kGraph | kPrint | 0, + /* 0x31(1) */ kDigit | kHexDigit | kGraph | kPrint | 0, + /* 0x32(2) */ kDigit | kHexDigit | kGraph | kPrint | 0, + /* 0x33(3) */ kDigit | kHexDigit | kGraph | kPrint | 0, + /* 0x34(4) */ kDigit | kHexDigit | kGraph | kPrint | 0, + /* 0x35(5) */ kDigit | kHexDigit | kGraph | kPrint | 0, + /* 0x36(6) */ kDigit | kHexDigit | kGraph | kPrint | 0, + /* 0x37(7) */ kDigit | kHexDigit | kGraph | kPrint | 0, + /* 0x38(8) */ kDigit | kHexDigit | kGraph | kPrint | 0, + /* 0x39(9) */ kDigit | kHexDigit | kGraph | kPrint | 0, + /* 0x3a(:) */ kPunct | kGraph | kPrint | 0, + /* 0x3b(;) */ kPunct | kGraph | kPrint | 0, + /* 0x3c(<) */ kPunct | kGraph | kPrint | 0, + /* 0x3d(=) */ kPunct | kGraph | kPrint | 0, + /* 0x3e(>) */ kPunct | kGraph | kPrint | 0, + /* 0x3f(?) */ kPunct | kGraph | kPrint | 0, + /* 0x40(@) */ kPunct | kGraph | kPrint | 0, + /* 0x41(A) */ kUpper | kHexDigit | kGraph | kPrint | 0, + /* 0x42(B) */ kUpper | kHexDigit | kGraph | kPrint | 0, + /* 0x43(C) */ kUpper | kHexDigit | kGraph | kPrint | 0, + /* 0x44(D) */ kUpper | kHexDigit | kGraph | kPrint | 0, + /* 0x45(E) */ kUpper | kHexDigit | kGraph | kPrint | 0, + /* 0x46(F) */ kUpper | kHexDigit | kGraph | kPrint | 0, + /* 0x47(G) */ kUpper | kGraph | kPrint | 0, + /* 0x48(H) */ kUpper | kGraph | kPrint | 0, + /* 0x49(I) */ kUpper | kGraph | kPrint | 0, + /* 0x4a(J) */ kUpper | kGraph | kPrint | 0, + /* 0x4b(K) */ kUpper | kGraph | kPrint | 0, + /* 0x4c(L) */ kUpper | kGraph | kPrint | 0, + /* 0x4d(M) */ kUpper | kGraph | kPrint | 0, + /* 0x4e(N) */ kUpper | kGraph | kPrint | 0, + /* 0x4f(O) */ kUpper | kGraph | kPrint | 0, + /* 0x50(P) */ kUpper | kGraph | kPrint | 0, + /* 0x51(Q) */ kUpper | kGraph | kPrint | 0, + /* 0x52(R) */ kUpper | kGraph | kPrint | 0, + /* 0x53(S) */ kUpper | kGraph | kPrint | 0, + /* 0x54(T) */ kUpper | kGraph | kPrint | 0, + /* 0x55(U) */ kUpper | kGraph | kPrint | 0, + /* 0x56(V) */ kUpper | kGraph | kPrint | 0, + /* 0x57(W) */ kUpper | kGraph | kPrint | 0, + /* 0x58(X) */ kUpper | kGraph | kPrint | 0, + /* 0x59(Y) */ kUpper | kGraph | kPrint | 0, + /* 0x5a(Z) */ kUpper | kGraph | kPrint | 0, + /* 0x5b([) */ kPunct | kGraph | kPrint | 0, + /* 0x5c(\) */ kPunct | kGraph | kPrint | 0, + /* 0x5d(]) */ kPunct | kGraph | kPrint | 0, + /* 0x5e(^) */ kPunct | kGraph | kPrint | 0, + /* 0x5f(_) */ kPunct | kGraph | kPrint | 0, + /* 0x60(`) */ kPunct | kGraph | kPrint | 0, + /* 0x61(a) */ kLower | kHexDigit | kGraph | kPrint | 0, + /* 0x62(b) */ kLower | kHexDigit | kGraph | kPrint | 0, + /* 0x63(c) */ kLower | kHexDigit | kGraph | kPrint | 0, + /* 0x64(d) */ kLower | kHexDigit | kGraph | kPrint | 0, + /* 0x65(e) */ kLower | kHexDigit | kGraph | kPrint | 0, + /* 0x66(f) */ kLower | kHexDigit | kGraph | kPrint | 0, + /* 0x67(g) */ kLower | kGraph | kPrint | 0, + /* 0x68(h) */ kLower | kGraph | kPrint | 0, + /* 0x69(i) */ kLower | kGraph | kPrint | 0, + /* 0x6a(j) */ kLower | kGraph | kPrint | 0, + /* 0x6b(k) */ kLower | kGraph | kPrint | 0, + /* 0x6c(l) */ kLower | kGraph | kPrint | 0, + /* 0x6d(m) */ kLower | kGraph | kPrint | 0, + /* 0x6e(n) */ kLower | kGraph | kPrint | 0, + /* 0x6f(o) */ kLower | kGraph | kPrint | 0, + /* 0x70(p) */ kLower | kGraph | kPrint | 0, + /* 0x71(q) */ kLower | kGraph | kPrint | 0, + /* 0x72(r) */ kLower | kGraph | kPrint | 0, + /* 0x73(s) */ kLower | kGraph | kPrint | 0, + /* 0x74(t) */ kLower | kGraph | kPrint | 0, + /* 0x75(u) */ kLower | kGraph | kPrint | 0, + /* 0x76(v) */ kLower | kGraph | kPrint | 0, + /* 0x77(w) */ kLower | kGraph | kPrint | 0, + /* 0x78(x) */ kLower | kGraph | kPrint | 0, + /* 0x79(y) */ kLower | kGraph | kPrint | 0, + /* 0x7a(z) */ kLower | kGraph | kPrint | 0, + /* 0x7b({) */ kPunct | kGraph | kPrint | 0, + /* 0x7c(|) */ kPunct | kGraph | kPrint | 0, + /* 0x7d(}) */ kPunct | kGraph | kPrint | 0, + /* 0x7e(~) */ kPunct | kGraph | kPrint | 0, + /* 0x7f( ) */ kControl | 0, + // all 0 delow + }; + return table[static_cast(c)]; + } + + static bool CharIncludeAnyTypeMask(char c, int mask) + { + return (GetCharTypeMask(c) & mask) != 0; + } + + static bool CharIncludeAallTypeMask(char c, int mask) + { + return (GetCharTypeMask(c) & mask) == mask; + } +}; + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_ASCII_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/atomic.h b/src/sofa/pbrpc/atomic.h new file mode 100644 index 0000000..7f7ada2 --- /dev/null +++ b/src/sofa/pbrpc/atomic.h @@ -0,0 +1,103 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_ATOMIC_H_ +#define _SOFA_PBRPC_ATOMIC_H_ + +#if !defined(__i386__) && !defined(__x86_64__) +#error "Arch not supprot!" +#endif + +#include + +namespace sofa { +namespace pbrpc { + +template +inline void atomic_inc(volatile T* n) +{ + asm volatile ("lock; incl %0;":"+m"(*n)::"cc"); +} +template +inline void atomic_dec(volatile T* n) +{ + asm volatile ("lock; decl %0;":"+m"(*n)::"cc"); +} +template +inline T atomic_add_ret_old(volatile T* n, T v) +{ + asm volatile ("lock; xaddl %1, %0;":"+m"(*n),"+r"(v)::"cc"); + return v; +} +template +inline T atomic_inc_ret_old(volatile T* n) +{ + T r = 1; + asm volatile ("lock; xaddl %1, %0;":"+m"(*n), "+r"(r)::"cc"); + return r; +} +template +inline T atomic_dec_ret_old(volatile T* n) +{ + T r = (T)-1; + asm volatile ("lock; xaddl %1, %0;":"+m"(*n), "+r"(r)::"cc"); + return r; +} +template +inline T atomic_add_ret_old64(volatile T* n, T v) +{ + asm volatile ("lock; xaddq %1, %0;":"+m"(*n),"+r"(v)::"cc"); + return v; +} +template +inline T atomic_inc_ret_old64(volatile T* n) +{ + T r = 1; + asm volatile ("lock; xaddq %1, %0;":"+m"(*n), "+r"(r)::"cc"); + return r; +} +template +inline T atomic_dec_ret_old64(volatile T* n) +{ + T r = (T)-1; + asm volatile ("lock; xaddq %1, %0;":"+m"(*n), "+r"(r)::"cc"); + return r; +} +template +inline void atomic_add(volatile T* n, T v) +{ + asm volatile ("lock; addl %1, %0;":"+m"(*n):"r"(v):"cc"); +} +template +inline void atomic_sub(volatile T* n, T v) +{ + asm volatile ("lock; subl %1, %0;":"+m"(*n):"r"(v):"cc"); +} +template +inline T atomic_cmpxchg(volatile T* n, C cmp, D dest) +{ + asm volatile ("lock; cmpxchgl %1, %0":"+m"(*n), "+r"(dest), "+a"(cmp)::"cc"); + return cmp; +} +// return old value +template +inline T atomic_swap(volatile T* lockword, T value) +{ + asm volatile ("lock; xchg %0, %1;" : "+r"(value), "+m"(*lockword)); + return value; +} +template +inline T atomic_comp_swap(volatile T* lockword, E exchange, C comperand) +{ + return atomic_cmpxchg(lockword, comperand, exchange); +} + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_ATOMIC_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/block_wrappers.cc b/src/sofa/pbrpc/block_wrappers.cc new file mode 100644 index 0000000..d1c56f8 --- /dev/null +++ b/src/sofa/pbrpc/block_wrappers.cc @@ -0,0 +1,229 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from `protobuf-zerocopy-compression': +// https://github.com/JohannesEbke/protobuf-zerocopy-compression +// +// Copyright (c) 2013, Johannes Ebke and Peter Waller. All rights reserved. +// Author: peter.waller@gmail.com (Peter Waller) +// Author: johannes@ebke.org (Johannes Ebke) + +#include + +#include +using google::protobuf::io::CodedInputStream; +using google::protobuf::io::CodedOutputStream; + +#include +#include +#include + +#if HAVE_SNAPPY +#include +#endif + +namespace sofa { +namespace pbrpc { + +const size_t BLOCKSIZE = 64 * 1024; + +BlockCompressionInputStream::BlockCompressionInputStream( + ZeroCopyInputStream* sub_stream) + : _output_buffer(NULL), _output_buffer_size(0), _sub_stream(NULL), _backed_up_bytes(0), + _byte_count(0) { + _raw_stream = sub_stream; + _sub_stream = new CodedInputStream(_raw_stream); + _sub_stream->SetTotalBytesLimit(1 << 30, 1 << 30); +} + +BlockCompressionInputStream::~BlockCompressionInputStream() { + delete _sub_stream; + delete[] _output_buffer; +} + +bool BlockCompressionInputStream::Skip(int /*count*/) { + SCHECK(false); + return false; +}; + +void BlockCompressionInputStream::BackUp(int count) { + if (count <= 0) return; + SCHECK(_output_buffer); + SCHECK_LE(static_cast(count), _output_buffer_size - _backed_up_bytes); + _backed_up_bytes += count; + _byte_count -= count; +}; + +void BlockCompressionInputStream::reset_input_stream() { + delete _sub_stream; + _sub_stream = new CodedInputStream(_raw_stream); + _sub_stream->SetTotalBytesLimit(1 << 30, 1 << 30); +} + +bool BlockCompressionInputStream::Next(const void** data, int* size) { + if (_backed_up_bytes) { + size_t skip = _output_buffer_size - _backed_up_bytes; + (*data) = _output_buffer + skip; + (*size) = _backed_up_bytes; + _backed_up_bytes = 0; + _byte_count += *size; + return true; + } + + uint32_t compressed_size = 0; + if (!_sub_stream->ReadVarint32(&compressed_size) || compressed_size > 2*BLOCKSIZE) { + return false; + } + + char * tempbuffer = new char[compressed_size]; + if (!_sub_stream->ReadRaw(tempbuffer, compressed_size)) { + delete[] tempbuffer; + return false; + } + + RawUncompress(tempbuffer, compressed_size); + delete[] tempbuffer; + + // TODO: probably call this only every Limit/BLOCKSIZE + if (_sub_stream->BytesUntilLimit() < 1024*1024) reset_input_stream(); + + (*data) = _output_buffer; + (*size) = _output_buffer_size; + _byte_count += *size; + return true; +} + +// ========================================================================= + +BlockCompressionOutputStream::BlockCompressionOutputStream( + ZeroCopyOutputStream* sub_stream) + : _input_buffer(NULL), _sub_stream(new CodedOutputStream(sub_stream)), _backed_up_bytes(0), + _byte_count(0) {} + +BlockCompressionOutputStream::~BlockCompressionOutputStream() { + if (_input_buffer) { + // The buffer is not empty, there is stuff yet to be written. + // This is necessary because we can't call virtual functions from any + // destructor. Often this results in a pure virtual function call. + // Call BlockCompressionOutputStream::Flush() before destroying + // this object. + SCHECK(false); + // Flush(); + } + delete _sub_stream; +} + +void BlockCompressionOutputStream::BackUp(int count) { + if (count <= 0) return; + SCHECK(_input_buffer); + SCHECK_LE(static_cast(count), BLOCKSIZE - _backed_up_bytes); + _backed_up_bytes += count; + _byte_count -= count; +} + +bool BlockCompressionOutputStream::Flush() +{ + size_t size = BLOCKSIZE - _backed_up_bytes; + if (!_input_buffer || size == 0) return true; + + size_t compressed_size = 0; + char * compressed_data = new char[MaxCompressedLength(size)]; + compressed_size = RawCompress(_input_buffer, size, compressed_data); + + SCHECK_LE(compressed_size, 2*BLOCKSIZE); + + uint32_t compressed_size_32 = static_cast(compressed_size); + _sub_stream->WriteVarint32(compressed_size_32); + _sub_stream->WriteRaw(compressed_data, compressed_size_32); + delete[] compressed_data; + + _backed_up_bytes = 0; + delete[] _input_buffer; + _input_buffer = 0; + return true; +} + +bool BlockCompressionOutputStream::Next(void** data, int* size) { + if (_backed_up_bytes) { + size_t skip = BLOCKSIZE - _backed_up_bytes; + (*data) = _input_buffer + skip; + (*size) = _backed_up_bytes; + _backed_up_bytes = 0; + _byte_count += *size; + return true; + } + if(_input_buffer) Flush(); + _input_buffer = new char[BLOCKSIZE]; + (*data) = _input_buffer; + (*size) = BLOCKSIZE; + _byte_count += *size; + return true; +} + + +#if HAVE_SNAPPY + +/// Snappy implementation + +void SnappyInputStream::RawUncompress(char* input_buffer, uint32_t compressed_size) { + size_t uncompressed_size; + bool success = ::snappy::GetUncompressedLength( + input_buffer, compressed_size, &uncompressed_size); + SCHECK(success); + + if (uncompressed_size > _output_buffer_size) { + delete[] _output_buffer; + _output_buffer_size = uncompressed_size; + _output_buffer = new char[_output_buffer_size]; + } + success = ::snappy::RawUncompress(input_buffer, compressed_size, + _output_buffer); + SCHECK(success); +} + + +uint32_t SnappyOutputStream::MaxCompressedLength(size_t input_size) +{ + return ::snappy::MaxCompressedLength(input_size); +} + +uint32_t SnappyOutputStream::RawCompress(char* input_buffer, size_t input_size, + char* output_buffer) +{ + size_t compressed_size = 0; + ::snappy::RawCompress(input_buffer, input_size, output_buffer, + &compressed_size); + return compressed_size; +} + +#endif // HAVE_SNAPPY + + +/// LZ4 implementation + +void LZ4InputStream::RawUncompress(char* input_buffer, uint32_t compressed_size) { + if (!_output_buffer) { + _output_buffer = new char[BLOCKSIZE]; + } + _output_buffer_size = LZ4_uncompress_unknownOutputSize(input_buffer, + _output_buffer, compressed_size, BLOCKSIZE); +} + +uint32_t LZ4OutputStream::MaxCompressedLength(size_t input_size) +{ + return LZ4_compressBound(input_size); +} + +uint32_t LZ4OutputStream::RawCompress(char* input_buffer, size_t input_size, + char* output_buffer) +{ + return LZ4_compress(input_buffer, output_buffer, input_size); +} + +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/block_wrappers.h b/src/sofa/pbrpc/block_wrappers.h new file mode 100644 index 0000000..22440e3 --- /dev/null +++ b/src/sofa/pbrpc/block_wrappers.h @@ -0,0 +1,138 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from `protobuf-zerocopy-compression': +// https://github.com/JohannesEbke/protobuf-zerocopy-compression +// +// Copyright (c) 2013, Johannes Ebke and Peter Waller. All rights reserved. +// Author: peter.waller@gmail.com (Peter Waller) +// Author: johannes@ebke.org (Johannes Ebke) + +#ifndef _SOFA_PBRPC_BLOCK_WRAPPER_H_ +#define _SOFA_PBRPC_BLOCK_WRAPPER_H_ + +#include +using google::protobuf::io::ZeroCopyInputStream; +using google::protobuf::io::ZeroCopyOutputStream; + +#include +using google::protobuf::io::CodedInputStream; +using google::protobuf::io::CodedOutputStream; + +#include + +namespace sofa { +namespace pbrpc { + +// This class provides scaffolding for implementing compression streams based +// on compression algorithms that do not support streaming operations but must +// be operated blockwise. +class BlockCompressionInputStream : public AbstractCompressedInputStream { + public: + explicit BlockCompressionInputStream(ZeroCopyInputStream* sub_stream); + virtual ~BlockCompressionInputStream(); + + bool Next(const void** data, int* size); + void BackUp(int count); + bool Skip(int count); + int64_t ByteCount() const { return _byte_count; } + bool ExpectAtEnd() { return true; } + + protected: + virtual void RawUncompress(char* input_buffer, uint32_t compressed_size) = 0; + + char* _output_buffer; + size_t _output_buffer_size; + + private: + + CodedInputStream* _sub_stream; + ZeroCopyInputStream* _raw_stream; + + int _backed_up_bytes; + size_t _byte_count; + + void reset_input_stream(); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(BlockCompressionInputStream); +}; + +class BlockCompressionOutputStream : public AbstractCompressedOutputStream { + public: + // Create a BlockCompressionOutputStream with default options. + explicit BlockCompressionOutputStream(ZeroCopyOutputStream* sub_stream); + virtual ~BlockCompressionOutputStream(); + + bool Next(void** data, int* size); + void BackUp(int count); + int64_t ByteCount() const { return _byte_count; }; + + bool Flush(); + bool Close() { return Flush(); } + + protected: + virtual uint32_t MaxCompressedLength(size_t input_size) = 0; + virtual uint32_t RawCompress(char* input_buffer, size_t input_size, char* output_buffer) = 0; + char* _input_buffer; + + private: + CodedOutputStream* _sub_stream; + + int _backed_up_bytes; + size_t _byte_count; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(BlockCompressionOutputStream); +}; + +#ifdef HAVE_SNAPPY + +class SnappyInputStream : public BlockCompressionInputStream { + public: + explicit SnappyInputStream(ZeroCopyInputStream* sub_stream) : BlockCompressionInputStream(sub_stream) {}; + + virtual void RawUncompress(char* input_buffer, uint32_t compressed_size); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SnappyInputStream); +}; + +class SnappyOutputStream : public BlockCompressionOutputStream { + public: + explicit SnappyOutputStream(ZeroCopyOutputStream* sub_stream) : BlockCompressionOutputStream(sub_stream) {}; + + virtual uint32_t MaxCompressedLength(size_t input_size); + virtual uint32_t RawCompress(char* input_buffer, size_t input_size, char* output_buffer); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SnappyOutputStream); +}; + +#endif + +class LZ4InputStream : public BlockCompressionInputStream { + public: + + explicit LZ4InputStream(ZeroCopyInputStream* sub_stream) : BlockCompressionInputStream(sub_stream) {}; + + virtual void RawUncompress(char* input_buffer, uint32_t compressed_size); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LZ4InputStream); +}; + +class LZ4OutputStream : public BlockCompressionOutputStream { + public: + explicit LZ4OutputStream(ZeroCopyOutputStream* sub_stream) : BlockCompressionOutputStream(sub_stream) {}; + + virtual uint32_t MaxCompressedLength(size_t input_size); + virtual uint32_t RawCompress(char* input_buffer, size_t input_size, char* output_buffer); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LZ4OutputStream); +}; + +} // namespace pbrpc +} // namepsace sofa + +#endif // _SOFA_PBRPC_BLOCK_WRAPPER_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/boost_system_error_code.cc b/src/sofa/pbrpc/boost_system_error_code.cc new file mode 100644 index 0000000..76b0fc4 --- /dev/null +++ b/src/sofa/pbrpc/boost_system_error_code.cc @@ -0,0 +1,440 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from boost. +// Boost Software License - Version 1.0 - August 17th, 2003 +// +// error_code support implementation file ----------------------------------// + +// Copyright Beman Dawes 2002, 2006 + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/system + +//----------------------------------------------------------------------------// + +#include + +// define BOOST_SYSTEM_SOURCE so that knows +// the library is being built (possibly exporting rather than importing code) +#define BOOST_SYSTEM_SOURCE + +#include +#include +#include +#include +#include +#include + +using namespace boost::system; +using namespace boost::system::errc; + +#include // for strerror/strerror_r + +# if defined( BOOST_WINDOWS_API ) +# include +# include "local_free_on_destruction.hpp" +# ifndef ERROR_INCORRECT_SIZE +# define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS +# endif +# endif + +//----------------------------------------------------------------------------// +#define WEAK __attribute__((weak)) + +namespace +{ +#if defined(__PGI) + using boost::system::errc::invalid_argument; +#endif + // standard error categories ---------------------------------------------// + + class generic_error_category : public error_category + { + public: + generic_error_category(){} + const char * name() const; + std::string message( int ev ) const; + }; + + class system_error_category : public error_category + { + public: + system_error_category(){} + const char * name() const; + std::string message( int ev ) const; + error_condition default_error_condition( int ev ) const; + }; + + // generic_error_category implementation ---------------------------------// + + WEAK const char * generic_error_category::name() const + { + return "generic"; + } + + WEAK std::string generic_error_category::message( int ev ) const + { + static std::string unknown_err( "Unknown error" ); + // strerror_r is preferred because it is always thread safe, + // however, we fallback to strerror in certain cases because: + // -- Windows doesn't provide strerror_r. + // -- HP and Sun do provide strerror_r on newer systems, but there is + // no way to tell if is available at runtime and in any case their + // versions of strerror are thread safe anyhow. + // -- Linux only sometimes provides strerror_r. + // -- Tru64 provides strerror_r only when compiled -pthread. + // -- VMS doesn't provide strerror_r, but on this platform, strerror is + // thread safe. + # if defined(BOOST_WINDOWS_API) || defined(__hpux) || defined(__sun)\ + || (defined(__linux) && (!defined(__USE_XOPEN2K) || defined(BOOST_SYSTEM_USE_STRERROR)))\ + || (defined(__osf__) && !defined(_REENTRANT))\ + || (defined(__INTEGRITY))\ + || (defined(__vms))\ + || (defined(__QNXNTO__)) + const char * c_str = std::strerror( ev ); + return c_str + ? std::string( c_str ) + : unknown_err; + # else // use strerror_r + char buf[64]; + char * bp = buf; + std::size_t sz = sizeof(buf); + # if defined(__CYGWIN__) || defined(__USE_GNU) + // Oddball version of strerror_r + const char * c_str = strerror_r( ev, bp, sz ); + return c_str + ? std::string( c_str ) + : unknown_err; + # else + // POSIX version of strerror_r + int result; + for (;;) + { + // strerror_r returns 0 on success, otherwise ERANGE if buffer too small, + // invalid_argument if ev not a valid error number + # if defined (__sgi) + const char * c_str = strerror( ev ); + result = 0; + return c_str + ? std::string( c_str ) + : unknown_err; + # else + result = strerror_r( ev, bp, sz ); + # endif + if (result == 0 ) + break; + else + { + # if defined(__linux) + // Linux strerror_r returns -1 on error, with error number in errno + result = errno; + # endif + if ( result != ERANGE ) break; + if ( sz > sizeof(buf) ) std::free( bp ); + sz *= 2; + if ( (bp = static_cast(std::malloc( sz ))) == 0 ) + return std::string( "ENOMEM" ); + } + } + std::string msg; + try + { + msg = ( ( result == invalid_argument ) ? "Unknown error" : bp ); + } + +# ifndef BOOST_NO_EXCEPTIONS + // See ticket #2098 + catch(...) + { + // just eat the exception + } +# endif + + if ( sz > sizeof(buf) ) std::free( bp ); + sz = 0; + return msg; + # endif // else POSIX version of strerror_r + # endif // else use strerror_r + } + // system_error_category implementation --------------------------------// + + WEAK const char * system_error_category::name() const + { + return "system"; + } + + WEAK error_condition system_error_category::default_error_condition( int ev ) const + { + switch ( ev ) + { + case 0: return make_error_condition( success ); +# if defined(BOOST_POSIX_API) + // POSIX-like O/S -> posix_errno decode table ---------------------------// + case E2BIG: return make_error_condition( argument_list_too_long ); + case EACCES: return make_error_condition( permission_denied ); + case EADDRINUSE: return make_error_condition( address_in_use ); + case EADDRNOTAVAIL: return make_error_condition( address_not_available ); + case EAFNOSUPPORT: return make_error_condition( address_family_not_supported ); + case EAGAIN: return make_error_condition( resource_unavailable_try_again ); +# if EALREADY != EBUSY // EALREADY and EBUSY are the same on QNX Neutrino + case EALREADY: return make_error_condition( connection_already_in_progress ); +# endif + case EBADF: return make_error_condition( bad_file_descriptor ); + case EBADMSG: return make_error_condition( bad_message ); + case EBUSY: return make_error_condition( device_or_resource_busy ); + case ECANCELED: return make_error_condition( operation_canceled ); + case ECHILD: return make_error_condition( no_child_process ); + case ECONNABORTED: return make_error_condition( connection_aborted ); + case ECONNREFUSED: return make_error_condition( connection_refused ); + case ECONNRESET: return make_error_condition( connection_reset ); + case EDEADLK: return make_error_condition( resource_deadlock_would_occur ); + case EDESTADDRREQ: return make_error_condition( destination_address_required ); + case EDOM: return make_error_condition( argument_out_of_domain ); + case EEXIST: return make_error_condition( file_exists ); + case EFAULT: return make_error_condition( bad_address ); + case EFBIG: return make_error_condition( file_too_large ); + case EHOSTUNREACH: return make_error_condition( host_unreachable ); + case EIDRM: return make_error_condition( identifier_removed ); + case EILSEQ: return make_error_condition( illegal_byte_sequence ); + case EINPROGRESS: return make_error_condition( operation_in_progress ); + case EINTR: return make_error_condition( interrupted ); + case EINVAL: return make_error_condition( invalid_argument ); + case EIO: return make_error_condition( io_error ); + case EISCONN: return make_error_condition( already_connected ); + case EISDIR: return make_error_condition( is_a_directory ); + case ELOOP: return make_error_condition( too_many_symbolic_link_levels ); + case EMFILE: return make_error_condition( too_many_files_open ); + case EMLINK: return make_error_condition( too_many_links ); + case EMSGSIZE: return make_error_condition( message_size ); + case ENAMETOOLONG: return make_error_condition( filename_too_long ); + case ENETDOWN: return make_error_condition( network_down ); + case ENETRESET: return make_error_condition( network_reset ); + case ENETUNREACH: return make_error_condition( network_unreachable ); + case ENFILE: return make_error_condition( too_many_files_open_in_system ); + case ENOBUFS: return make_error_condition( no_buffer_space ); + case ENODATA: return make_error_condition( no_message_available ); + case ENODEV: return make_error_condition( no_such_device ); + case ENOENT: return make_error_condition( no_such_file_or_directory ); + case ENOEXEC: return make_error_condition( executable_format_error ); + case ENOLCK: return make_error_condition( no_lock_available ); + case ENOLINK: return make_error_condition( no_link ); + case ENOMEM: return make_error_condition( not_enough_memory ); + case ENOMSG: return make_error_condition( no_message ); + case ENOPROTOOPT: return make_error_condition( no_protocol_option ); + case ENOSPC: return make_error_condition( no_space_on_device ); + case ENOSR: return make_error_condition( no_stream_resources ); + case ENOSTR: return make_error_condition( not_a_stream ); + case ENOSYS: return make_error_condition( function_not_supported ); + case ENOTCONN: return make_error_condition( not_connected ); + case ENOTDIR: return make_error_condition( not_a_directory ); + # if ENOTEMPTY != EEXIST // AIX treats ENOTEMPTY and EEXIST as the same value + case ENOTEMPTY: return make_error_condition( directory_not_empty ); + # endif // ENOTEMPTY != EEXIST + # if ENOTRECOVERABLE != ECONNRESET // the same on some Broadcom chips + case ENOTRECOVERABLE: return make_error_condition( state_not_recoverable ); + # endif // ENOTRECOVERABLE != ECONNRESET + case ENOTSOCK: return make_error_condition( not_a_socket ); + case ENOTSUP: return make_error_condition( not_supported ); + case ENOTTY: return make_error_condition( inappropriate_io_control_operation ); + case ENXIO: return make_error_condition( no_such_device_or_address ); + # if EOPNOTSUPP != ENOTSUP + case EOPNOTSUPP: return make_error_condition( operation_not_supported ); + # endif // EOPNOTSUPP != ENOTSUP + case EOVERFLOW: return make_error_condition( value_too_large ); + # if EOWNERDEAD != ECONNABORTED // the same on some Broadcom chips + case EOWNERDEAD: return make_error_condition( owner_dead ); + # endif // EOWNERDEAD != ECONNABORTED + case EPERM: return make_error_condition( operation_not_permitted ); + case EPIPE: return make_error_condition( broken_pipe ); + case EPROTO: return make_error_condition( protocol_error ); + case EPROTONOSUPPORT: return make_error_condition( protocol_not_supported ); + case EPROTOTYPE: return make_error_condition( wrong_protocol_type ); + case ERANGE: return make_error_condition( result_out_of_range ); + case EROFS: return make_error_condition( read_only_file_system ); + case ESPIPE: return make_error_condition( invalid_seek ); + case ESRCH: return make_error_condition( no_such_process ); + case ETIME: return make_error_condition( stream_timeout ); + case ETIMEDOUT: return make_error_condition( timed_out ); + case ETXTBSY: return make_error_condition( text_file_busy ); + # if EAGAIN != EWOULDBLOCK + case EWOULDBLOCK: return make_error_condition( operation_would_block ); + # endif // EAGAIN != EWOULDBLOCK + case EXDEV: return make_error_condition( cross_device_link ); + #else + // Windows system -> posix_errno decode table ---------------------------// + // see WinError.h comments for descriptions of errors + case ERROR_ACCESS_DENIED: return make_error_condition( permission_denied ); + case ERROR_ALREADY_EXISTS: return make_error_condition( file_exists ); + case ERROR_BAD_UNIT: return make_error_condition( no_such_device ); + case ERROR_BUFFER_OVERFLOW: return make_error_condition( filename_too_long ); + case ERROR_BUSY: return make_error_condition( device_or_resource_busy ); + case ERROR_BUSY_DRIVE: return make_error_condition( device_or_resource_busy ); + case ERROR_CANNOT_MAKE: return make_error_condition( permission_denied ); + case ERROR_CANTOPEN: return make_error_condition( io_error ); + case ERROR_CANTREAD: return make_error_condition( io_error ); + case ERROR_CANTWRITE: return make_error_condition( io_error ); + case ERROR_CURRENT_DIRECTORY: return make_error_condition( permission_denied ); + case ERROR_DEV_NOT_EXIST: return make_error_condition( no_such_device ); + case ERROR_DEVICE_IN_USE: return make_error_condition( device_or_resource_busy ); + case ERROR_DIR_NOT_EMPTY: return make_error_condition( directory_not_empty ); + case ERROR_DIRECTORY: return make_error_condition( invalid_argument ); // WinError.h: "The directory name is invalid" + case ERROR_DISK_FULL: return make_error_condition( no_space_on_device ); + case ERROR_FILE_EXISTS: return make_error_condition( file_exists ); + case ERROR_FILE_NOT_FOUND: return make_error_condition( no_such_file_or_directory ); + case ERROR_HANDLE_DISK_FULL: return make_error_condition( no_space_on_device ); + case ERROR_INVALID_ACCESS: return make_error_condition( permission_denied ); + case ERROR_INVALID_DRIVE: return make_error_condition( no_such_device ); + case ERROR_INVALID_FUNCTION: return make_error_condition( function_not_supported ); + case ERROR_INVALID_HANDLE: return make_error_condition( invalid_argument ); + case ERROR_INVALID_NAME: return make_error_condition( invalid_argument ); + case ERROR_LOCK_VIOLATION: return make_error_condition( no_lock_available ); + case ERROR_LOCKED: return make_error_condition( no_lock_available ); + case ERROR_NEGATIVE_SEEK: return make_error_condition( invalid_argument ); + case ERROR_NOACCESS: return make_error_condition( permission_denied ); + case ERROR_NOT_ENOUGH_MEMORY: return make_error_condition( not_enough_memory ); + case ERROR_NOT_READY: return make_error_condition( resource_unavailable_try_again ); + case ERROR_NOT_SAME_DEVICE: return make_error_condition( cross_device_link ); + case ERROR_OPEN_FAILED: return make_error_condition( io_error ); + case ERROR_OPEN_FILES: return make_error_condition( device_or_resource_busy ); + case ERROR_OPERATION_ABORTED: return make_error_condition( operation_canceled ); + case ERROR_OUTOFMEMORY: return make_error_condition( not_enough_memory ); + case ERROR_PATH_NOT_FOUND: return make_error_condition( no_such_file_or_directory ); + case ERROR_READ_FAULT: return make_error_condition( io_error ); + case ERROR_RETRY: return make_error_condition( resource_unavailable_try_again ); + case ERROR_SEEK: return make_error_condition( io_error ); + case ERROR_SHARING_VIOLATION: return make_error_condition( permission_denied ); + case ERROR_TOO_MANY_OPEN_FILES: return make_error_condition( too_many_files_open ); + case ERROR_WRITE_FAULT: return make_error_condition( io_error ); + case ERROR_WRITE_PROTECT: return make_error_condition( permission_denied ); + case WSAEACCES: return make_error_condition( permission_denied ); + case WSAEADDRINUSE: return make_error_condition( address_in_use ); + case WSAEADDRNOTAVAIL: return make_error_condition( address_not_available ); + case WSAEAFNOSUPPORT: return make_error_condition( address_family_not_supported ); + case WSAEALREADY: return make_error_condition( connection_already_in_progress ); + case WSAEBADF: return make_error_condition( bad_file_descriptor ); + case WSAECONNABORTED: return make_error_condition( connection_aborted ); + case WSAECONNREFUSED: return make_error_condition( connection_refused ); + case WSAECONNRESET: return make_error_condition( connection_reset ); + case WSAEDESTADDRREQ: return make_error_condition( destination_address_required ); + case WSAEFAULT: return make_error_condition( bad_address ); + case WSAEHOSTUNREACH: return make_error_condition( host_unreachable ); + case WSAEINPROGRESS: return make_error_condition( operation_in_progress ); + case WSAEINTR: return make_error_condition( interrupted ); + case WSAEINVAL: return make_error_condition( invalid_argument ); + case WSAEISCONN: return make_error_condition( already_connected ); + case WSAEMFILE: return make_error_condition( too_many_files_open ); + case WSAEMSGSIZE: return make_error_condition( message_size ); + case WSAENAMETOOLONG: return make_error_condition( filename_too_long ); + case WSAENETDOWN: return make_error_condition( network_down ); + case WSAENETRESET: return make_error_condition( network_reset ); + case WSAENETUNREACH: return make_error_condition( network_unreachable ); + case WSAENOBUFS: return make_error_condition( no_buffer_space ); + case WSAENOPROTOOPT: return make_error_condition( no_protocol_option ); + case WSAENOTCONN: return make_error_condition( not_connected ); + case WSAENOTSOCK: return make_error_condition( not_a_socket ); + case WSAEOPNOTSUPP: return make_error_condition( operation_not_supported ); + case WSAEPROTONOSUPPORT: return make_error_condition( protocol_not_supported ); + case WSAEPROTOTYPE: return make_error_condition( wrong_protocol_type ); + case WSAETIMEDOUT: return make_error_condition( timed_out ); + case WSAEWOULDBLOCK: return make_error_condition( operation_would_block ); + #endif + default: return error_condition( ev, system_category() ); + } + } + +# if !defined( BOOST_WINDOWS_API ) + + WEAK std::string system_error_category::message( int ev ) const + { + return generic_category().message( ev ); + } +# else + + WEAK std::string system_error_category::message( int ev ) const + { +# ifndef BOOST_NO_ANSI_APIS + LPVOID lpMsgBuf = 0; + DWORD retval = ::FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + ev, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPSTR) &lpMsgBuf, + 0, + NULL + ); + detail::local_free_on_destruction lfod(lpMsgBuf); + if (retval == 0) + return std::string("Unknown error"); + + std::string str( static_cast(lpMsgBuf) ); +# else // WinCE workaround + LPVOID lpMsgBuf = 0; + DWORD retval = ::FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + ev, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPWSTR) &lpMsgBuf, + 0, + NULL + ); + detail::local_free_on_destruction lfod(lpMsgBuf); + if (retval == 0) + return std::string("Unknown error"); + + int num_chars = (wcslen( static_cast(lpMsgBuf) ) + 1) * 2; + LPSTR narrow_buffer = (LPSTR)_alloca( num_chars ); + if (::WideCharToMultiByte(CP_ACP, 0, static_cast(lpMsgBuf), -1, narrow_buffer, num_chars, NULL, NULL) == 0) + return std::string("Unknown error"); + + std::string str( narrow_buffer ); +# endif + while ( str.size() + && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') ) + str.erase( str.size()-1 ); + if ( str.size() && str[str.size()-1] == '.' ) + { str.erase( str.size()-1 ); } + return str; + } +# endif + +} // unnamed namespace + +namespace boost +{ + namespace system + { + +# ifndef BOOST_SYSTEM_NO_DEPRECATED + BOOST_SYSTEM_DECL error_code throws; // "throw on error" special error_code; + // note that it doesn't matter if this + // isn't initialized before use since + // the only use is to take its + // address for comparison purposes +# endif + + BOOST_SYSTEM_DECL const error_category & system_category() + { + static const system_error_category system_category_const; + return system_category_const; + } + + BOOST_SYSTEM_DECL const error_category & generic_category() + { + static const generic_error_category generic_category_const; + return generic_category_const; + } + + } // namespace system +} // namespace boost diff --git a/src/sofa/pbrpc/buf_handle.h b/src/sofa/pbrpc/buf_handle.h new file mode 100644 index 0000000..2a2ed67 --- /dev/null +++ b/src/sofa/pbrpc/buf_handle.h @@ -0,0 +1,38 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_BUF_HANDLE_H_ +#define _SOFA_PBRPC_BUF_HANDLE_H_ + +namespace sofa { +namespace pbrpc { + +struct BufHandle +{ + char* data; // block header + int size; // data size + union { + int capacity; // block capacity, used by WriteBuffer + int offset; // start position in the block, used by ReadBuffer + }; + + BufHandle(char* _data, int _capacity) + : data(_data) + , size(0) + , capacity(_capacity) {} + + BufHandle(char* _data, int _size, int _offset) + : data(_data) + , size(_size) + , offset(_offset) {} +}; // class BufHandle + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_BUF_HANDLE_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/buffer.cc b/src/sofa/pbrpc/buffer.cc new file mode 100644 index 0000000..6e31ed8 --- /dev/null +++ b/src/sofa/pbrpc/buffer.cc @@ -0,0 +1,268 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include +#include + +namespace sofa { +namespace pbrpc { + +ReadBuffer::ReadBuffer() + : _total_bytes(0) + , _cur_it(_buf_list.begin()) + , _cur_pos(0) + , _last_bytes(0) + , _read_bytes(0) +{} + +ReadBuffer::~ReadBuffer() +{ + for (BufHandleListIterator it = _buf_list.begin(); + it != _buf_list.end(); ++it) + { + TranBufPool::free(it->data); + } + _buf_list.clear(); +} + +void ReadBuffer::Append(const BufHandle& buf_handle) +{ + SCHECK_GT(buf_handle.size, 0); + _buf_list.push_back(buf_handle); + TranBufPool::add_ref(buf_handle.data); + _total_bytes += buf_handle.size; + _cur_it = _buf_list.begin(); +} + +int64 ReadBuffer::TotalCount() const +{ + return _total_bytes; +} + +int ReadBuffer::BlockCount() const +{ + return _buf_list.size(); +} + +bool ReadBuffer::Next(const void** data, int* size) +{ + if (_cur_it != _buf_list.end()) + { + SCHECK_LT(_cur_pos, _cur_it->size); + *data = _cur_it->data + _cur_it->offset + _cur_pos; + *size = _cur_it->size - _cur_pos; + ++_cur_it; + _cur_pos = 0; + _last_bytes = *size; + _read_bytes += _last_bytes; + return true; + } + else + { + _last_bytes = 0; + return false; + } +} + +// BackUp() can only be called after a successful Next(). +// "count" should be greater than or equal to 0. +void ReadBuffer::BackUp(int count) +{ + SCHECK_GT(_last_bytes, 0); + SCHECK_GE(count, 0); + SCHECK_LE(count, _last_bytes); + if (count > 0) + { + --_cur_it; + _cur_pos = _cur_it->size - count; + } + _last_bytes = 0; + _read_bytes -= count; +} + +// "count" should be greater than or equal to 0. +bool ReadBuffer::Skip(int count) +{ + SCHECK_GE(count, 0); + const void* data; + int size; + while (count > 0 && Next(&data, &size)) + { + if (size > count) + { + BackUp(size - count); + size = count; + } + count -= size; + } + _last_bytes = 0; + return count == 0; +} + +int64 ReadBuffer::ByteCount() const +{ + return _read_bytes; +} + +WriteBuffer::WriteBuffer() + : _total_capacity(0) + , _last_bytes(0) + , _write_bytes(0) +{} + +WriteBuffer::~WriteBuffer() +{ + for (BufHandleListIterator it = _buf_list.begin(); + it != _buf_list.end(); ++it) + { + TranBufPool::free(it->data); + } + _buf_list.clear(); +} + +int64 WriteBuffer::TotalCapacity() const +{ + return _total_capacity; +} + +int WriteBuffer::BlockCount() const +{ + return _buf_list.size(); +} + +void WriteBuffer::SwapOut(ReadBuffer* is) +{ + while (!_buf_list.empty()) + { + BufHandle& buf_handle = _buf_list.front(); + if (buf_handle.size > 0) + { + buf_handle.offset = 0; // capacity -> offset + is->Append(buf_handle); + } + TranBufPool::free(buf_handle.data); + _buf_list.pop_front(); + } + _total_capacity = 0; + _last_bytes = 0; + _write_bytes = 0; +} + +int64 WriteBuffer::Reserve(int count) +{ + SCHECK_GT(count, 0); + int64 head = ByteCount(); + void* data; + int size; + while (count > 0) + { + if (!Next(&data, &size)) + return -1; + if (size > count) + { + BackUp(size - count); + count = 0; + } + else + { + count -= size; + } + } + return head; +} + +void WriteBuffer::SetData(int64 pos, const char* data, int size) +{ + SCHECK_GE(pos, 0); + SCHECK_GT(size, 0); + SCHECK_LE(pos + size, ByteCount()); + BufHandleListIterator cur_it = _buf_list.begin(); + int cur_offset = 0; + while (pos > 0) + { + SCHECK(cur_it != _buf_list.end()); + int cur_size = cur_it->size - cur_offset; + if (cur_size > pos) + { + cur_offset += pos; + pos = 0; + } + else + { + pos -= cur_size; + ++cur_it; + cur_offset = 0; + } + } + while (size > 0) + { + SCHECK(cur_it != _buf_list.end()); + int cur_size = cur_it->size - cur_offset; + if (cur_size > size) + { + memcpy(cur_it->data + cur_offset, data, size); + size = 0; + } + else + { + memcpy(cur_it->data + cur_offset, data, cur_size); + size -= cur_size; + ++cur_it; + cur_offset = 0; + } + } +} + +bool WriteBuffer::Next(void** data, int* size) +{ + BufHandleListReverseIterator last = _buf_list.rbegin(); + if (last == _buf_list.rend() || last->size == last->capacity) + { + if (!Extend()) + { + _last_bytes = 0; + return false; + } + last = _buf_list.rbegin(); + } + *data = last->data + last->size; + *size = last->capacity - last->size; + last->size = last->capacity; + _last_bytes = *size; + _write_bytes += _last_bytes; + return true; +} + +// BackUp() can only be called after a successful Next(). +// "count" should be greater than or equal to 0. +void WriteBuffer::BackUp(int count) +{ + SCHECK_GT(_last_bytes, 0); + SCHECK_GE(count, 0); + SCHECK_LE(count, _last_bytes); + _buf_list.back().size -= count; + _last_bytes = 0; + _write_bytes -= count; +} + +int64 WriteBuffer::ByteCount() const +{ + return _write_bytes; +} + +bool WriteBuffer::Extend() +{ + char* block = static_cast(TranBufPool::malloc()); + if (block == NULL) return false; + _buf_list.push_back(BufHandle(block, TranBufPool::block_size())); + _total_capacity += TranBufPool::block_size(); + return true; +} + +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/buffer.h b/src/sofa/pbrpc/buffer.h new file mode 100644 index 0000000..5f43e25 --- /dev/null +++ b/src/sofa/pbrpc/buffer.h @@ -0,0 +1,124 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_BUFFER_H_ +#define _SOFA_PBRPC_BUFFER_H_ + +#include + +#include + +#include +#include + +namespace sofa { +namespace pbrpc { + +// Defined in this file. +class ReadBuffer; +typedef sofa::pbrpc::shared_ptr ReadBufferPtr; +class WriteBuffer; +typedef sofa::pbrpc::shared_ptr WriteBufferPtr; + +typedef std::deque BufHandleList; +typedef std::deque::iterator BufHandleListIterator; +typedef std::deque::reverse_iterator BufHandleListReverseIterator; + +class ReadBuffer : public google::protobuf::io::ZeroCopyInputStream +{ +public: + ReadBuffer(); + virtual ~ReadBuffer(); + + // Append a buf handle to the buffer. + // + // Preconditions: + // * No method Next(), Backup() or Skip() have been called before. + // * The size of "buf_handle" should be greater than 0. + void Append(const BufHandle& buf_handle); + + // Get the total byte count of the buffer. + int64 TotalCount() const; + + // Get the block count occupied by the buffer. + int BlockCount() const; + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size); + void BackUp(int count); + bool Skip(int count); + int64 ByteCount() const; + +private: + BufHandleList _buf_list; + int64 _total_bytes; // total bytes in the buffer + BufHandleListIterator _cur_it; + int _cur_pos; + int _last_bytes; // last read bytes + int64 _read_bytes; // total read bytes + + SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(ReadBuffer); +}; // class ReadBuffer + +class WriteBuffer : public google::protobuf::io::ZeroCopyOutputStream +{ +public: + WriteBuffer(); + virtual ~WriteBuffer(); + + // Get the total capacity of the buffer. + int64 TotalCapacity() const; + + // Get the block count occupied by the buffer. + int BlockCount() const; + + // Swap out data from this output stream and append to the input stream "is". + // The "is" should not be null. + // + // Postconditions: + // * This buffer is cleared afterward, just as a new output buffer. + void SwapOut(ReadBuffer* is); + + // Reserve some space in the buffer. + // If succeed, return the head position of reserved space. + // If failed, return -1. + // + // Preconditions: + // * "count" > 0 + int64 Reserve(int count); + + // Set data in the buffer, start from "pos". + // + // Preconditions: + // * "pos" >= 0 + // * "data" != NULL && "size" > 0 + // * "pos" + "size" <= ByteCount() + void SetData(int64 pos, const char* data, int size); + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size); + void BackUp(int count); + int64 ByteCount() const; + +private: + // Add a new block to the end of the buffer. + bool Extend(); + +private: + BufHandleList _buf_list; + int64 _total_capacity; + int _last_bytes; // last write bytes + int64 _write_bytes; // total write bytes + + SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(WriteBuffer); +}; // class WriteBuffer + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_BUFFER_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/builtin_service.pb.cc b/src/sofa/pbrpc/builtin_service.pb.cc new file mode 100644 index 0000000..28538d2 --- /dev/null +++ b/src/sofa/pbrpc/builtin_service.pb.cc @@ -0,0 +1,4612 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "sofa/pbrpc/builtin_service.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace sofa { +namespace pbrpc { +namespace builtin { + +namespace { + +const ::google::protobuf::Descriptor* HealthRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + HealthRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* HealthResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + HealthResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* ServerOptions_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ServerOptions_reflection_ = NULL; +const ::google::protobuf::Descriptor* ServerOptionsRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ServerOptionsRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* ServerOptionsResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ServerOptionsResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* UpdateOptionsRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + UpdateOptionsRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* UpdateOptionsResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + UpdateOptionsResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* ServerStatusRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ServerStatusRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* ServerStatusResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ServerStatusResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* ListServiceRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ListServiceRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* ListServiceResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ListServiceResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* MethodStat_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + MethodStat_reflection_ = NULL; +const ::google::protobuf::Descriptor* ServiceStat_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ServiceStat_reflection_ = NULL; +const ::google::protobuf::Descriptor* StatRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + StatRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* StatResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + StatResponse_reflection_ = NULL; +const ::google::protobuf::ServiceDescriptor* BuiltinService_descriptor_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto() { + protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "sofa/pbrpc/builtin_service.proto"); + GOOGLE_CHECK(file != NULL); + HealthRequest_descriptor_ = file->message_type(0); + static const int HealthRequest_offsets_[1] = { + }; + HealthRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + HealthRequest_descriptor_, + HealthRequest::default_instance_, + HealthRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(HealthRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(HealthRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(HealthRequest)); + HealthResponse_descriptor_ = file->message_type(1); + static const int HealthResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(HealthResponse, health_), + }; + HealthResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + HealthResponse_descriptor_, + HealthResponse::default_instance_, + HealthResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(HealthResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(HealthResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(HealthResponse)); + ServerOptions_descriptor_ = file->message_type(2); + static const int ServerOptions_offsets_[7] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerOptions, work_thread_num_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerOptions, keep_alive_time_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerOptions, max_pending_buffer_size_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerOptions, max_throughput_in_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerOptions, max_throughput_out_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerOptions, disable_builtin_services_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerOptions, disable_list_service_), + }; + ServerOptions_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ServerOptions_descriptor_, + ServerOptions::default_instance_, + ServerOptions_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerOptions, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerOptions, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ServerOptions)); + ServerOptionsRequest_descriptor_ = file->message_type(3); + static const int ServerOptionsRequest_offsets_[1] = { + }; + ServerOptionsRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ServerOptionsRequest_descriptor_, + ServerOptionsRequest::default_instance_, + ServerOptionsRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerOptionsRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerOptionsRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ServerOptionsRequest)); + ServerOptionsResponse_descriptor_ = file->message_type(4); + static const int ServerOptionsResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerOptionsResponse, options_), + }; + ServerOptionsResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ServerOptionsResponse_descriptor_, + ServerOptionsResponse::default_instance_, + ServerOptionsResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerOptionsResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerOptionsResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ServerOptionsResponse)); + UpdateOptionsRequest_descriptor_ = file->message_type(5); + static const int UpdateOptionsRequest_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UpdateOptionsRequest, options_), + }; + UpdateOptionsRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + UpdateOptionsRequest_descriptor_, + UpdateOptionsRequest::default_instance_, + UpdateOptionsRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UpdateOptionsRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UpdateOptionsRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(UpdateOptionsRequest)); + UpdateOptionsResponse_descriptor_ = file->message_type(6); + static const int UpdateOptionsResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UpdateOptionsResponse, options_), + }; + UpdateOptionsResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + UpdateOptionsResponse_descriptor_, + UpdateOptionsResponse::default_instance_, + UpdateOptionsResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UpdateOptionsResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UpdateOptionsResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(UpdateOptionsResponse)); + ServerStatusRequest_descriptor_ = file->message_type(7); + static const int ServerStatusRequest_offsets_[1] = { + }; + ServerStatusRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ServerStatusRequest_descriptor_, + ServerStatusRequest::default_instance_, + ServerStatusRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerStatusRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerStatusRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ServerStatusRequest)); + ServerStatusResponse_descriptor_ = file->message_type(8); + static const int ServerStatusResponse_offsets_[6] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerStatusResponse, is_listening_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerStatusResponse, connection_count_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerStatusResponse, service_count_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerStatusResponse, pending_message_count_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerStatusResponse, pending_buffer_size_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerStatusResponse, pending_data_size_), + }; + ServerStatusResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ServerStatusResponse_descriptor_, + ServerStatusResponse::default_instance_, + ServerStatusResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerStatusResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerStatusResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ServerStatusResponse)); + ListServiceRequest_descriptor_ = file->message_type(9); + static const int ListServiceRequest_offsets_[1] = { + }; + ListServiceRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ListServiceRequest_descriptor_, + ListServiceRequest::default_instance_, + ListServiceRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListServiceRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListServiceRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ListServiceRequest)); + ListServiceResponse_descriptor_ = file->message_type(10); + static const int ListServiceResponse_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListServiceResponse, services_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListServiceResponse, files_), + }; + ListServiceResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ListServiceResponse_descriptor_, + ListServiceResponse::default_instance_, + ListServiceResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListServiceResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListServiceResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ListServiceResponse)); + MethodStat_descriptor_ = file->message_type(11); + static const int MethodStat_offsets_[7] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodStat, method_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodStat, succeed_count_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodStat, succeed_avg_time_us_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodStat, succeed_max_time_us_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodStat, failed_count_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodStat, failed_avg_time_us_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodStat, failed_max_time_us_), + }; + MethodStat_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + MethodStat_descriptor_, + MethodStat::default_instance_, + MethodStat_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodStat, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodStat, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(MethodStat)); + ServiceStat_descriptor_ = file->message_type(12); + static const int ServiceStat_offsets_[5] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceStat, service_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceStat, period_seconds_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceStat, succeed_count_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceStat, failed_count_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceStat, method_stats_), + }; + ServiceStat_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ServiceStat_descriptor_, + ServiceStat::default_instance_, + ServiceStat_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceStat, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceStat, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ServiceStat)); + StatRequest_descriptor_ = file->message_type(13); + static const int StatRequest_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatRequest, service_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatRequest, period_seconds_), + }; + StatRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + StatRequest_descriptor_, + StatRequest::default_instance_, + StatRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(StatRequest)); + StatResponse_descriptor_ = file->message_type(14); + static const int StatResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatResponse, service_stats_), + }; + StatResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + StatResponse_descriptor_, + StatResponse::default_instance_, + StatResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(StatResponse)); + BuiltinService_descriptor_ = file->service(0); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + HealthRequest_descriptor_, &HealthRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + HealthResponse_descriptor_, &HealthResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ServerOptions_descriptor_, &ServerOptions::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ServerOptionsRequest_descriptor_, &ServerOptionsRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ServerOptionsResponse_descriptor_, &ServerOptionsResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + UpdateOptionsRequest_descriptor_, &UpdateOptionsRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + UpdateOptionsResponse_descriptor_, &UpdateOptionsResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ServerStatusRequest_descriptor_, &ServerStatusRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ServerStatusResponse_descriptor_, &ServerStatusResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ListServiceRequest_descriptor_, &ListServiceRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ListServiceResponse_descriptor_, &ListServiceResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + MethodStat_descriptor_, &MethodStat::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ServiceStat_descriptor_, &ServiceStat::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + StatRequest_descriptor_, &StatRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + StatResponse_descriptor_, &StatResponse::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto() { + delete HealthRequest::default_instance_; + delete HealthRequest_reflection_; + delete HealthResponse::default_instance_; + delete HealthResponse_reflection_; + delete ServerOptions::default_instance_; + delete ServerOptions_reflection_; + delete ServerOptionsRequest::default_instance_; + delete ServerOptionsRequest_reflection_; + delete ServerOptionsResponse::default_instance_; + delete ServerOptionsResponse_reflection_; + delete UpdateOptionsRequest::default_instance_; + delete UpdateOptionsRequest_reflection_; + delete UpdateOptionsResponse::default_instance_; + delete UpdateOptionsResponse_reflection_; + delete ServerStatusRequest::default_instance_; + delete ServerStatusRequest_reflection_; + delete ServerStatusResponse::default_instance_; + delete ServerStatusResponse_reflection_; + delete ListServiceRequest::default_instance_; + delete ListServiceRequest_reflection_; + delete ListServiceResponse::default_instance_; + delete ListServiceResponse_reflection_; + delete MethodStat::default_instance_; + delete MethodStat_reflection_; + delete ServiceStat::default_instance_; + delete ServiceStat_reflection_; + delete StatRequest::default_instance_; + delete StatRequest_reflection_; + delete StatResponse::default_instance_; + delete StatResponse_reflection_; +} + +void protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + ::sofa::pbrpc::protobuf_AddDesc_sofa_2fpbrpc_2frpc_5foption_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n sofa/pbrpc/builtin_service.proto\022\022sofa" + ".pbrpc.builtin\032 google/protobuf/descript" + "or.proto\032\033sofa/pbrpc/rpc_option.proto\"\017\n" + "\rHealthRequest\" \n\016HealthResponse\022\016\n\006heal" + "th\030\001 \001(\t\"\331\001\n\rServerOptions\022\027\n\017work_threa" + "d_num\030\001 \001(\003\022\027\n\017keep_alive_time\030\002 \001(\003\022\037\n\027" + "max_pending_buffer_size\030\003 \001(\003\022\031\n\021max_thr" + "oughput_in\030\004 \001(\003\022\032\n\022max_throughput_out\030\005" + " \001(\003\022 \n\030disable_builtin_services\030\006 \001(\010\022\034" + "\n\024disable_list_service\030\007 \001(\010\"\026\n\024ServerOp" + "tionsRequest\"K\n\025ServerOptionsResponse\0222\n" + "\007options\030\001 \001(\0132!.sofa.pbrpc.builtin.Serv" + "erOptions\"J\n\024UpdateOptionsRequest\0222\n\007opt" + "ions\030\001 \001(\0132!.sofa.pbrpc.builtin.ServerOp" + "tions\"K\n\025UpdateOptionsResponse\0222\n\007option" + "s\030\001 \001(\0132!.sofa.pbrpc.builtin.ServerOptio" + "ns\"\025\n\023ServerStatusRequest\"\264\001\n\024ServerStat" + "usResponse\022\024\n\014is_listening\030\001 \001(\010\022\030\n\020conn" + "ection_count\030\002 \001(\003\022\025\n\rservice_count\030\003 \001(" + "\003\022\035\n\025pending_message_count\030\004 \001(\003\022\033\n\023pend" + "ing_buffer_size\030\005 \001(\003\022\031\n\021pending_data_si" + "ze\030\006 \001(\003\"\024\n\022ListServiceRequest\"\\\n\023ListSe" + "rviceResponse\022\020\n\010services\030\001 \003(\t\0223\n\005files" + "\030\002 \003(\0132$.google.protobuf.FileDescriptorP" + "roto\"\300\001\n\nMethodStat\022\023\n\013method_name\030\001 \001(\t" + "\022\025\n\rsucceed_count\030\002 \001(\003\022\033\n\023succeed_avg_t" + "ime_us\030\003 \001(\002\022\033\n\023succeed_max_time_us\030\004 \001(" + "\003\022\024\n\014failed_count\030\005 \001(\003\022\032\n\022failed_avg_ti" + "me_us\030\006 \001(\002\022\032\n\022failed_max_time_us\030\007 \001(\003\"" + "\236\001\n\013ServiceStat\022\024\n\014service_name\030\001 \001(\t\022\026\n" + "\016period_seconds\030\002 \001(\003\022\025\n\rsucceed_count\030\003" + " \001(\003\022\024\n\014failed_count\030\004 \001(\003\0224\n\014method_sta" + "ts\030\005 \003(\0132\036.sofa.pbrpc.builtin.MethodStat" + "\"D\n\013StatRequest\022\031\n\014service_name\030\001 \001(\t:\003a" + "ll\022\032\n\016period_seconds\030\002 \001(\003:\00260\"F\n\014StatRe" + "sponse\0226\n\rservice_stats\030\001 \003(\0132\037.sofa.pbr" + "pc.builtin.ServiceStat2\310\004\n\016BuiltinServic" + "e\022O\n\006Health\022!.sofa.pbrpc.builtin.HealthR" + "equest\032\".sofa.pbrpc.builtin.HealthRespon" + "se\022d\n\rServerOptions\022(.sofa.pbrpc.builtin" + ".ServerOptionsRequest\032).sofa.pbrpc.built" + "in.ServerOptionsResponse\022d\n\rUpdateOption" + "s\022(.sofa.pbrpc.builtin.UpdateOptionsRequ" + "est\032).sofa.pbrpc.builtin.UpdateOptionsRe" + "sponse\022a\n\014ServerStatus\022\'.sofa.pbrpc.buil" + "tin.ServerStatusRequest\032(.sofa.pbrpc.bui" + "ltin.ServerStatusResponse\022d\n\013ListService" + "\022&.sofa.pbrpc.builtin.ListServiceRequest" + "\032\'.sofa.pbrpc.builtin.ListServiceRespons" + "e\"\004\220\342\t\001\022I\n\004Stat\022\037.sofa.pbrpc.builtin.Sta" + "tRequest\032 .sofa.pbrpc.builtin.StatRespon" + "se\032\005\200\342\t\270\027B\003\200\001\001", 2054); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "sofa/pbrpc/builtin_service.proto", &protobuf_RegisterTypes); + HealthRequest::default_instance_ = new HealthRequest(); + HealthResponse::default_instance_ = new HealthResponse(); + ServerOptions::default_instance_ = new ServerOptions(); + ServerOptionsRequest::default_instance_ = new ServerOptionsRequest(); + ServerOptionsResponse::default_instance_ = new ServerOptionsResponse(); + UpdateOptionsRequest::default_instance_ = new UpdateOptionsRequest(); + UpdateOptionsResponse::default_instance_ = new UpdateOptionsResponse(); + ServerStatusRequest::default_instance_ = new ServerStatusRequest(); + ServerStatusResponse::default_instance_ = new ServerStatusResponse(); + ListServiceRequest::default_instance_ = new ListServiceRequest(); + ListServiceResponse::default_instance_ = new ListServiceResponse(); + MethodStat::default_instance_ = new MethodStat(); + ServiceStat::default_instance_ = new ServiceStat(); + StatRequest::default_instance_ = new StatRequest(); + StatResponse::default_instance_ = new StatResponse(); + HealthRequest::default_instance_->InitAsDefaultInstance(); + HealthResponse::default_instance_->InitAsDefaultInstance(); + ServerOptions::default_instance_->InitAsDefaultInstance(); + ServerOptionsRequest::default_instance_->InitAsDefaultInstance(); + ServerOptionsResponse::default_instance_->InitAsDefaultInstance(); + UpdateOptionsRequest::default_instance_->InitAsDefaultInstance(); + UpdateOptionsResponse::default_instance_->InitAsDefaultInstance(); + ServerStatusRequest::default_instance_->InitAsDefaultInstance(); + ServerStatusResponse::default_instance_->InitAsDefaultInstance(); + ListServiceRequest::default_instance_->InitAsDefaultInstance(); + ListServiceResponse::default_instance_->InitAsDefaultInstance(); + MethodStat::default_instance_->InitAsDefaultInstance(); + ServiceStat::default_instance_->InitAsDefaultInstance(); + StatRequest::default_instance_->InitAsDefaultInstance(); + StatResponse::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto { + StaticDescriptorInitializer_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto() { + protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + } +} static_descriptor_initializer_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto_; + + +// =================================================================== + +#ifndef _MSC_VER +#endif // !_MSC_VER + +HealthRequest::HealthRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void HealthRequest::InitAsDefaultInstance() { +} + +HealthRequest::HealthRequest(const HealthRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void HealthRequest::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +HealthRequest::~HealthRequest() { + SharedDtor(); +} + +void HealthRequest::SharedDtor() { + if (this != default_instance_) { + } +} + +void HealthRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* HealthRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return HealthRequest_descriptor_; +} + +const HealthRequest& HealthRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); return *default_instance_; +} + +HealthRequest* HealthRequest::default_instance_ = NULL; + +HealthRequest* HealthRequest::New() const { + return new HealthRequest; +} + +void HealthRequest::Clear() { + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool HealthRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + } + return true; +#undef DO_ +} + +void HealthRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* HealthRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int HealthRequest::ByteSize() const { + int total_size = 0; + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void HealthRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const HealthRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void HealthRequest::MergeFrom(const HealthRequest& from) { + GOOGLE_CHECK_NE(&from, this); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void HealthRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void HealthRequest::CopyFrom(const HealthRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool HealthRequest::IsInitialized() const { + + return true; +} + +void HealthRequest::Swap(HealthRequest* other) { + if (other != this) { + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata HealthRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = HealthRequest_descriptor_; + metadata.reflection = HealthRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int HealthResponse::kHealthFieldNumber; +#endif // !_MSC_VER + +HealthResponse::HealthResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void HealthResponse::InitAsDefaultInstance() { +} + +HealthResponse::HealthResponse(const HealthResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void HealthResponse::SharedCtor() { + _cached_size_ = 0; + health_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +HealthResponse::~HealthResponse() { + SharedDtor(); +} + +void HealthResponse::SharedDtor() { + if (health_ != &::google::protobuf::internal::kEmptyString) { + delete health_; + } + if (this != default_instance_) { + } +} + +void HealthResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* HealthResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return HealthResponse_descriptor_; +} + +const HealthResponse& HealthResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); return *default_instance_; +} + +HealthResponse* HealthResponse::default_instance_ = NULL; + +HealthResponse* HealthResponse::New() const { + return new HealthResponse; +} + +void HealthResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_health()) { + if (health_ != &::google::protobuf::internal::kEmptyString) { + health_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool HealthResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string health = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_health())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->health().data(), this->health().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void HealthResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional string health = 1; + if (has_health()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->health().data(), this->health().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->health(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* HealthResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional string health = 1; + if (has_health()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->health().data(), this->health().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->health(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int HealthResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string health = 1; + if (has_health()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->health()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void HealthResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const HealthResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void HealthResponse::MergeFrom(const HealthResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_health()) { + set_health(from.health()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void HealthResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void HealthResponse::CopyFrom(const HealthResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool HealthResponse::IsInitialized() const { + + return true; +} + +void HealthResponse::Swap(HealthResponse* other) { + if (other != this) { + std::swap(health_, other->health_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata HealthResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = HealthResponse_descriptor_; + metadata.reflection = HealthResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ServerOptions::kWorkThreadNumFieldNumber; +const int ServerOptions::kKeepAliveTimeFieldNumber; +const int ServerOptions::kMaxPendingBufferSizeFieldNumber; +const int ServerOptions::kMaxThroughputInFieldNumber; +const int ServerOptions::kMaxThroughputOutFieldNumber; +const int ServerOptions::kDisableBuiltinServicesFieldNumber; +const int ServerOptions::kDisableListServiceFieldNumber; +#endif // !_MSC_VER + +ServerOptions::ServerOptions() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ServerOptions::InitAsDefaultInstance() { +} + +ServerOptions::ServerOptions(const ServerOptions& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ServerOptions::SharedCtor() { + _cached_size_ = 0; + work_thread_num_ = GOOGLE_LONGLONG(0); + keep_alive_time_ = GOOGLE_LONGLONG(0); + max_pending_buffer_size_ = GOOGLE_LONGLONG(0); + max_throughput_in_ = GOOGLE_LONGLONG(0); + max_throughput_out_ = GOOGLE_LONGLONG(0); + disable_builtin_services_ = false; + disable_list_service_ = false; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ServerOptions::~ServerOptions() { + SharedDtor(); +} + +void ServerOptions::SharedDtor() { + if (this != default_instance_) { + } +} + +void ServerOptions::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ServerOptions::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ServerOptions_descriptor_; +} + +const ServerOptions& ServerOptions::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); return *default_instance_; +} + +ServerOptions* ServerOptions::default_instance_ = NULL; + +ServerOptions* ServerOptions::New() const { + return new ServerOptions; +} + +void ServerOptions::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + work_thread_num_ = GOOGLE_LONGLONG(0); + keep_alive_time_ = GOOGLE_LONGLONG(0); + max_pending_buffer_size_ = GOOGLE_LONGLONG(0); + max_throughput_in_ = GOOGLE_LONGLONG(0); + max_throughput_out_ = GOOGLE_LONGLONG(0); + disable_builtin_services_ = false; + disable_list_service_ = false; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ServerOptions::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional int64 work_thread_num = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &work_thread_num_))); + set_has_work_thread_num(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_keep_alive_time; + break; + } + + // optional int64 keep_alive_time = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_keep_alive_time: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &keep_alive_time_))); + set_has_keep_alive_time(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(24)) goto parse_max_pending_buffer_size; + break; + } + + // optional int64 max_pending_buffer_size = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_max_pending_buffer_size: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &max_pending_buffer_size_))); + set_has_max_pending_buffer_size(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(32)) goto parse_max_throughput_in; + break; + } + + // optional int64 max_throughput_in = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_max_throughput_in: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &max_throughput_in_))); + set_has_max_throughput_in(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(40)) goto parse_max_throughput_out; + break; + } + + // optional int64 max_throughput_out = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_max_throughput_out: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &max_throughput_out_))); + set_has_max_throughput_out(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(48)) goto parse_disable_builtin_services; + break; + } + + // optional bool disable_builtin_services = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_disable_builtin_services: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &disable_builtin_services_))); + set_has_disable_builtin_services(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(56)) goto parse_disable_list_service; + break; + } + + // optional bool disable_list_service = 7; + case 7: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_disable_list_service: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &disable_list_service_))); + set_has_disable_list_service(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ServerOptions::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional int64 work_thread_num = 1; + if (has_work_thread_num()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(1, this->work_thread_num(), output); + } + + // optional int64 keep_alive_time = 2; + if (has_keep_alive_time()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(2, this->keep_alive_time(), output); + } + + // optional int64 max_pending_buffer_size = 3; + if (has_max_pending_buffer_size()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(3, this->max_pending_buffer_size(), output); + } + + // optional int64 max_throughput_in = 4; + if (has_max_throughput_in()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(4, this->max_throughput_in(), output); + } + + // optional int64 max_throughput_out = 5; + if (has_max_throughput_out()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(5, this->max_throughput_out(), output); + } + + // optional bool disable_builtin_services = 6; + if (has_disable_builtin_services()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(6, this->disable_builtin_services(), output); + } + + // optional bool disable_list_service = 7; + if (has_disable_list_service()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(7, this->disable_list_service(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ServerOptions::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional int64 work_thread_num = 1; + if (has_work_thread_num()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(1, this->work_thread_num(), target); + } + + // optional int64 keep_alive_time = 2; + if (has_keep_alive_time()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(2, this->keep_alive_time(), target); + } + + // optional int64 max_pending_buffer_size = 3; + if (has_max_pending_buffer_size()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(3, this->max_pending_buffer_size(), target); + } + + // optional int64 max_throughput_in = 4; + if (has_max_throughput_in()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(4, this->max_throughput_in(), target); + } + + // optional int64 max_throughput_out = 5; + if (has_max_throughput_out()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(5, this->max_throughput_out(), target); + } + + // optional bool disable_builtin_services = 6; + if (has_disable_builtin_services()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(6, this->disable_builtin_services(), target); + } + + // optional bool disable_list_service = 7; + if (has_disable_list_service()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(7, this->disable_list_service(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ServerOptions::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional int64 work_thread_num = 1; + if (has_work_thread_num()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->work_thread_num()); + } + + // optional int64 keep_alive_time = 2; + if (has_keep_alive_time()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->keep_alive_time()); + } + + // optional int64 max_pending_buffer_size = 3; + if (has_max_pending_buffer_size()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->max_pending_buffer_size()); + } + + // optional int64 max_throughput_in = 4; + if (has_max_throughput_in()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->max_throughput_in()); + } + + // optional int64 max_throughput_out = 5; + if (has_max_throughput_out()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->max_throughput_out()); + } + + // optional bool disable_builtin_services = 6; + if (has_disable_builtin_services()) { + total_size += 1 + 1; + } + + // optional bool disable_list_service = 7; + if (has_disable_list_service()) { + total_size += 1 + 1; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ServerOptions::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ServerOptions* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ServerOptions::MergeFrom(const ServerOptions& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_work_thread_num()) { + set_work_thread_num(from.work_thread_num()); + } + if (from.has_keep_alive_time()) { + set_keep_alive_time(from.keep_alive_time()); + } + if (from.has_max_pending_buffer_size()) { + set_max_pending_buffer_size(from.max_pending_buffer_size()); + } + if (from.has_max_throughput_in()) { + set_max_throughput_in(from.max_throughput_in()); + } + if (from.has_max_throughput_out()) { + set_max_throughput_out(from.max_throughput_out()); + } + if (from.has_disable_builtin_services()) { + set_disable_builtin_services(from.disable_builtin_services()); + } + if (from.has_disable_list_service()) { + set_disable_list_service(from.disable_list_service()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ServerOptions::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ServerOptions::CopyFrom(const ServerOptions& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ServerOptions::IsInitialized() const { + + return true; +} + +void ServerOptions::Swap(ServerOptions* other) { + if (other != this) { + std::swap(work_thread_num_, other->work_thread_num_); + std::swap(keep_alive_time_, other->keep_alive_time_); + std::swap(max_pending_buffer_size_, other->max_pending_buffer_size_); + std::swap(max_throughput_in_, other->max_throughput_in_); + std::swap(max_throughput_out_, other->max_throughput_out_); + std::swap(disable_builtin_services_, other->disable_builtin_services_); + std::swap(disable_list_service_, other->disable_list_service_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ServerOptions::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ServerOptions_descriptor_; + metadata.reflection = ServerOptions_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +#endif // !_MSC_VER + +ServerOptionsRequest::ServerOptionsRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ServerOptionsRequest::InitAsDefaultInstance() { +} + +ServerOptionsRequest::ServerOptionsRequest(const ServerOptionsRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ServerOptionsRequest::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ServerOptionsRequest::~ServerOptionsRequest() { + SharedDtor(); +} + +void ServerOptionsRequest::SharedDtor() { + if (this != default_instance_) { + } +} + +void ServerOptionsRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ServerOptionsRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ServerOptionsRequest_descriptor_; +} + +const ServerOptionsRequest& ServerOptionsRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); return *default_instance_; +} + +ServerOptionsRequest* ServerOptionsRequest::default_instance_ = NULL; + +ServerOptionsRequest* ServerOptionsRequest::New() const { + return new ServerOptionsRequest; +} + +void ServerOptionsRequest::Clear() { + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ServerOptionsRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + } + return true; +#undef DO_ +} + +void ServerOptionsRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ServerOptionsRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ServerOptionsRequest::ByteSize() const { + int total_size = 0; + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ServerOptionsRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ServerOptionsRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ServerOptionsRequest::MergeFrom(const ServerOptionsRequest& from) { + GOOGLE_CHECK_NE(&from, this); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ServerOptionsRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ServerOptionsRequest::CopyFrom(const ServerOptionsRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ServerOptionsRequest::IsInitialized() const { + + return true; +} + +void ServerOptionsRequest::Swap(ServerOptionsRequest* other) { + if (other != this) { + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ServerOptionsRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ServerOptionsRequest_descriptor_; + metadata.reflection = ServerOptionsRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ServerOptionsResponse::kOptionsFieldNumber; +#endif // !_MSC_VER + +ServerOptionsResponse::ServerOptionsResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ServerOptionsResponse::InitAsDefaultInstance() { + options_ = const_cast< ::sofa::pbrpc::builtin::ServerOptions*>(&::sofa::pbrpc::builtin::ServerOptions::default_instance()); +} + +ServerOptionsResponse::ServerOptionsResponse(const ServerOptionsResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ServerOptionsResponse::SharedCtor() { + _cached_size_ = 0; + options_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ServerOptionsResponse::~ServerOptionsResponse() { + SharedDtor(); +} + +void ServerOptionsResponse::SharedDtor() { + if (this != default_instance_) { + delete options_; + } +} + +void ServerOptionsResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ServerOptionsResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ServerOptionsResponse_descriptor_; +} + +const ServerOptionsResponse& ServerOptionsResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); return *default_instance_; +} + +ServerOptionsResponse* ServerOptionsResponse::default_instance_ = NULL; + +ServerOptionsResponse* ServerOptionsResponse::New() const { + return new ServerOptionsResponse; +} + +void ServerOptionsResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_options()) { + if (options_ != NULL) options_->::sofa::pbrpc::builtin::ServerOptions::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ServerOptionsResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional .sofa.pbrpc.builtin.ServerOptions options = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_options())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ServerOptionsResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional .sofa.pbrpc.builtin.ServerOptions options = 1; + if (has_options()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->options(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ServerOptionsResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional .sofa.pbrpc.builtin.ServerOptions options = 1; + if (has_options()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->options(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ServerOptionsResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional .sofa.pbrpc.builtin.ServerOptions options = 1; + if (has_options()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->options()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ServerOptionsResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ServerOptionsResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ServerOptionsResponse::MergeFrom(const ServerOptionsResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_options()) { + mutable_options()->::sofa::pbrpc::builtin::ServerOptions::MergeFrom(from.options()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ServerOptionsResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ServerOptionsResponse::CopyFrom(const ServerOptionsResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ServerOptionsResponse::IsInitialized() const { + + return true; +} + +void ServerOptionsResponse::Swap(ServerOptionsResponse* other) { + if (other != this) { + std::swap(options_, other->options_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ServerOptionsResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ServerOptionsResponse_descriptor_; + metadata.reflection = ServerOptionsResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int UpdateOptionsRequest::kOptionsFieldNumber; +#endif // !_MSC_VER + +UpdateOptionsRequest::UpdateOptionsRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void UpdateOptionsRequest::InitAsDefaultInstance() { + options_ = const_cast< ::sofa::pbrpc::builtin::ServerOptions*>(&::sofa::pbrpc::builtin::ServerOptions::default_instance()); +} + +UpdateOptionsRequest::UpdateOptionsRequest(const UpdateOptionsRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void UpdateOptionsRequest::SharedCtor() { + _cached_size_ = 0; + options_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +UpdateOptionsRequest::~UpdateOptionsRequest() { + SharedDtor(); +} + +void UpdateOptionsRequest::SharedDtor() { + if (this != default_instance_) { + delete options_; + } +} + +void UpdateOptionsRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* UpdateOptionsRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return UpdateOptionsRequest_descriptor_; +} + +const UpdateOptionsRequest& UpdateOptionsRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); return *default_instance_; +} + +UpdateOptionsRequest* UpdateOptionsRequest::default_instance_ = NULL; + +UpdateOptionsRequest* UpdateOptionsRequest::New() const { + return new UpdateOptionsRequest; +} + +void UpdateOptionsRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_options()) { + if (options_ != NULL) options_->::sofa::pbrpc::builtin::ServerOptions::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool UpdateOptionsRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional .sofa.pbrpc.builtin.ServerOptions options = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_options())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void UpdateOptionsRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional .sofa.pbrpc.builtin.ServerOptions options = 1; + if (has_options()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->options(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* UpdateOptionsRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional .sofa.pbrpc.builtin.ServerOptions options = 1; + if (has_options()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->options(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int UpdateOptionsRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional .sofa.pbrpc.builtin.ServerOptions options = 1; + if (has_options()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->options()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void UpdateOptionsRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const UpdateOptionsRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void UpdateOptionsRequest::MergeFrom(const UpdateOptionsRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_options()) { + mutable_options()->::sofa::pbrpc::builtin::ServerOptions::MergeFrom(from.options()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void UpdateOptionsRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void UpdateOptionsRequest::CopyFrom(const UpdateOptionsRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool UpdateOptionsRequest::IsInitialized() const { + + return true; +} + +void UpdateOptionsRequest::Swap(UpdateOptionsRequest* other) { + if (other != this) { + std::swap(options_, other->options_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata UpdateOptionsRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = UpdateOptionsRequest_descriptor_; + metadata.reflection = UpdateOptionsRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int UpdateOptionsResponse::kOptionsFieldNumber; +#endif // !_MSC_VER + +UpdateOptionsResponse::UpdateOptionsResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void UpdateOptionsResponse::InitAsDefaultInstance() { + options_ = const_cast< ::sofa::pbrpc::builtin::ServerOptions*>(&::sofa::pbrpc::builtin::ServerOptions::default_instance()); +} + +UpdateOptionsResponse::UpdateOptionsResponse(const UpdateOptionsResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void UpdateOptionsResponse::SharedCtor() { + _cached_size_ = 0; + options_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +UpdateOptionsResponse::~UpdateOptionsResponse() { + SharedDtor(); +} + +void UpdateOptionsResponse::SharedDtor() { + if (this != default_instance_) { + delete options_; + } +} + +void UpdateOptionsResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* UpdateOptionsResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return UpdateOptionsResponse_descriptor_; +} + +const UpdateOptionsResponse& UpdateOptionsResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); return *default_instance_; +} + +UpdateOptionsResponse* UpdateOptionsResponse::default_instance_ = NULL; + +UpdateOptionsResponse* UpdateOptionsResponse::New() const { + return new UpdateOptionsResponse; +} + +void UpdateOptionsResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_options()) { + if (options_ != NULL) options_->::sofa::pbrpc::builtin::ServerOptions::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool UpdateOptionsResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional .sofa.pbrpc.builtin.ServerOptions options = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_options())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void UpdateOptionsResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional .sofa.pbrpc.builtin.ServerOptions options = 1; + if (has_options()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->options(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* UpdateOptionsResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional .sofa.pbrpc.builtin.ServerOptions options = 1; + if (has_options()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->options(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int UpdateOptionsResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional .sofa.pbrpc.builtin.ServerOptions options = 1; + if (has_options()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->options()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void UpdateOptionsResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const UpdateOptionsResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void UpdateOptionsResponse::MergeFrom(const UpdateOptionsResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_options()) { + mutable_options()->::sofa::pbrpc::builtin::ServerOptions::MergeFrom(from.options()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void UpdateOptionsResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void UpdateOptionsResponse::CopyFrom(const UpdateOptionsResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool UpdateOptionsResponse::IsInitialized() const { + + return true; +} + +void UpdateOptionsResponse::Swap(UpdateOptionsResponse* other) { + if (other != this) { + std::swap(options_, other->options_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata UpdateOptionsResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = UpdateOptionsResponse_descriptor_; + metadata.reflection = UpdateOptionsResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +#endif // !_MSC_VER + +ServerStatusRequest::ServerStatusRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ServerStatusRequest::InitAsDefaultInstance() { +} + +ServerStatusRequest::ServerStatusRequest(const ServerStatusRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ServerStatusRequest::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ServerStatusRequest::~ServerStatusRequest() { + SharedDtor(); +} + +void ServerStatusRequest::SharedDtor() { + if (this != default_instance_) { + } +} + +void ServerStatusRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ServerStatusRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ServerStatusRequest_descriptor_; +} + +const ServerStatusRequest& ServerStatusRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); return *default_instance_; +} + +ServerStatusRequest* ServerStatusRequest::default_instance_ = NULL; + +ServerStatusRequest* ServerStatusRequest::New() const { + return new ServerStatusRequest; +} + +void ServerStatusRequest::Clear() { + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ServerStatusRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + } + return true; +#undef DO_ +} + +void ServerStatusRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ServerStatusRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ServerStatusRequest::ByteSize() const { + int total_size = 0; + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ServerStatusRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ServerStatusRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ServerStatusRequest::MergeFrom(const ServerStatusRequest& from) { + GOOGLE_CHECK_NE(&from, this); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ServerStatusRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ServerStatusRequest::CopyFrom(const ServerStatusRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ServerStatusRequest::IsInitialized() const { + + return true; +} + +void ServerStatusRequest::Swap(ServerStatusRequest* other) { + if (other != this) { + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ServerStatusRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ServerStatusRequest_descriptor_; + metadata.reflection = ServerStatusRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ServerStatusResponse::kIsListeningFieldNumber; +const int ServerStatusResponse::kConnectionCountFieldNumber; +const int ServerStatusResponse::kServiceCountFieldNumber; +const int ServerStatusResponse::kPendingMessageCountFieldNumber; +const int ServerStatusResponse::kPendingBufferSizeFieldNumber; +const int ServerStatusResponse::kPendingDataSizeFieldNumber; +#endif // !_MSC_VER + +ServerStatusResponse::ServerStatusResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ServerStatusResponse::InitAsDefaultInstance() { +} + +ServerStatusResponse::ServerStatusResponse(const ServerStatusResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ServerStatusResponse::SharedCtor() { + _cached_size_ = 0; + is_listening_ = false; + connection_count_ = GOOGLE_LONGLONG(0); + service_count_ = GOOGLE_LONGLONG(0); + pending_message_count_ = GOOGLE_LONGLONG(0); + pending_buffer_size_ = GOOGLE_LONGLONG(0); + pending_data_size_ = GOOGLE_LONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ServerStatusResponse::~ServerStatusResponse() { + SharedDtor(); +} + +void ServerStatusResponse::SharedDtor() { + if (this != default_instance_) { + } +} + +void ServerStatusResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ServerStatusResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ServerStatusResponse_descriptor_; +} + +const ServerStatusResponse& ServerStatusResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); return *default_instance_; +} + +ServerStatusResponse* ServerStatusResponse::default_instance_ = NULL; + +ServerStatusResponse* ServerStatusResponse::New() const { + return new ServerStatusResponse; +} + +void ServerStatusResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + is_listening_ = false; + connection_count_ = GOOGLE_LONGLONG(0); + service_count_ = GOOGLE_LONGLONG(0); + pending_message_count_ = GOOGLE_LONGLONG(0); + pending_buffer_size_ = GOOGLE_LONGLONG(0); + pending_data_size_ = GOOGLE_LONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ServerStatusResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional bool is_listening = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &is_listening_))); + set_has_is_listening(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_connection_count; + break; + } + + // optional int64 connection_count = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_connection_count: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &connection_count_))); + set_has_connection_count(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(24)) goto parse_service_count; + break; + } + + // optional int64 service_count = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_service_count: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &service_count_))); + set_has_service_count(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(32)) goto parse_pending_message_count; + break; + } + + // optional int64 pending_message_count = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_pending_message_count: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &pending_message_count_))); + set_has_pending_message_count(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(40)) goto parse_pending_buffer_size; + break; + } + + // optional int64 pending_buffer_size = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_pending_buffer_size: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &pending_buffer_size_))); + set_has_pending_buffer_size(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(48)) goto parse_pending_data_size; + break; + } + + // optional int64 pending_data_size = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_pending_data_size: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &pending_data_size_))); + set_has_pending_data_size(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ServerStatusResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional bool is_listening = 1; + if (has_is_listening()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->is_listening(), output); + } + + // optional int64 connection_count = 2; + if (has_connection_count()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(2, this->connection_count(), output); + } + + // optional int64 service_count = 3; + if (has_service_count()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(3, this->service_count(), output); + } + + // optional int64 pending_message_count = 4; + if (has_pending_message_count()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(4, this->pending_message_count(), output); + } + + // optional int64 pending_buffer_size = 5; + if (has_pending_buffer_size()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(5, this->pending_buffer_size(), output); + } + + // optional int64 pending_data_size = 6; + if (has_pending_data_size()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(6, this->pending_data_size(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ServerStatusResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional bool is_listening = 1; + if (has_is_listening()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->is_listening(), target); + } + + // optional int64 connection_count = 2; + if (has_connection_count()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(2, this->connection_count(), target); + } + + // optional int64 service_count = 3; + if (has_service_count()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(3, this->service_count(), target); + } + + // optional int64 pending_message_count = 4; + if (has_pending_message_count()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(4, this->pending_message_count(), target); + } + + // optional int64 pending_buffer_size = 5; + if (has_pending_buffer_size()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(5, this->pending_buffer_size(), target); + } + + // optional int64 pending_data_size = 6; + if (has_pending_data_size()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(6, this->pending_data_size(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ServerStatusResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional bool is_listening = 1; + if (has_is_listening()) { + total_size += 1 + 1; + } + + // optional int64 connection_count = 2; + if (has_connection_count()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->connection_count()); + } + + // optional int64 service_count = 3; + if (has_service_count()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->service_count()); + } + + // optional int64 pending_message_count = 4; + if (has_pending_message_count()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->pending_message_count()); + } + + // optional int64 pending_buffer_size = 5; + if (has_pending_buffer_size()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->pending_buffer_size()); + } + + // optional int64 pending_data_size = 6; + if (has_pending_data_size()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->pending_data_size()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ServerStatusResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ServerStatusResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ServerStatusResponse::MergeFrom(const ServerStatusResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_is_listening()) { + set_is_listening(from.is_listening()); + } + if (from.has_connection_count()) { + set_connection_count(from.connection_count()); + } + if (from.has_service_count()) { + set_service_count(from.service_count()); + } + if (from.has_pending_message_count()) { + set_pending_message_count(from.pending_message_count()); + } + if (from.has_pending_buffer_size()) { + set_pending_buffer_size(from.pending_buffer_size()); + } + if (from.has_pending_data_size()) { + set_pending_data_size(from.pending_data_size()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ServerStatusResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ServerStatusResponse::CopyFrom(const ServerStatusResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ServerStatusResponse::IsInitialized() const { + + return true; +} + +void ServerStatusResponse::Swap(ServerStatusResponse* other) { + if (other != this) { + std::swap(is_listening_, other->is_listening_); + std::swap(connection_count_, other->connection_count_); + std::swap(service_count_, other->service_count_); + std::swap(pending_message_count_, other->pending_message_count_); + std::swap(pending_buffer_size_, other->pending_buffer_size_); + std::swap(pending_data_size_, other->pending_data_size_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ServerStatusResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ServerStatusResponse_descriptor_; + metadata.reflection = ServerStatusResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +#endif // !_MSC_VER + +ListServiceRequest::ListServiceRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ListServiceRequest::InitAsDefaultInstance() { +} + +ListServiceRequest::ListServiceRequest(const ListServiceRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ListServiceRequest::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ListServiceRequest::~ListServiceRequest() { + SharedDtor(); +} + +void ListServiceRequest::SharedDtor() { + if (this != default_instance_) { + } +} + +void ListServiceRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ListServiceRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ListServiceRequest_descriptor_; +} + +const ListServiceRequest& ListServiceRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); return *default_instance_; +} + +ListServiceRequest* ListServiceRequest::default_instance_ = NULL; + +ListServiceRequest* ListServiceRequest::New() const { + return new ListServiceRequest; +} + +void ListServiceRequest::Clear() { + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ListServiceRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + } + return true; +#undef DO_ +} + +void ListServiceRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ListServiceRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ListServiceRequest::ByteSize() const { + int total_size = 0; + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ListServiceRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ListServiceRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ListServiceRequest::MergeFrom(const ListServiceRequest& from) { + GOOGLE_CHECK_NE(&from, this); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ListServiceRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ListServiceRequest::CopyFrom(const ListServiceRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ListServiceRequest::IsInitialized() const { + + return true; +} + +void ListServiceRequest::Swap(ListServiceRequest* other) { + if (other != this) { + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ListServiceRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ListServiceRequest_descriptor_; + metadata.reflection = ListServiceRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ListServiceResponse::kServicesFieldNumber; +const int ListServiceResponse::kFilesFieldNumber; +#endif // !_MSC_VER + +ListServiceResponse::ListServiceResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ListServiceResponse::InitAsDefaultInstance() { +} + +ListServiceResponse::ListServiceResponse(const ListServiceResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ListServiceResponse::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ListServiceResponse::~ListServiceResponse() { + SharedDtor(); +} + +void ListServiceResponse::SharedDtor() { + if (this != default_instance_) { + } +} + +void ListServiceResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ListServiceResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ListServiceResponse_descriptor_; +} + +const ListServiceResponse& ListServiceResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); return *default_instance_; +} + +ListServiceResponse* ListServiceResponse::default_instance_ = NULL; + +ListServiceResponse* ListServiceResponse::New() const { + return new ListServiceResponse; +} + +void ListServiceResponse::Clear() { + services_.Clear(); + files_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ListServiceResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated string services = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_services: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_services())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->services(0).data(), this->services(0).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_services; + if (input->ExpectTag(18)) goto parse_files; + break; + } + + // repeated .google.protobuf.FileDescriptorProto files = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_files: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_files())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_files; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ListServiceResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated string services = 1; + for (int i = 0; i < this->services_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->services(i).data(), this->services(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->services(i), output); + } + + // repeated .google.protobuf.FileDescriptorProto files = 2; + for (int i = 0; i < this->files_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->files(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ListServiceResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated string services = 1; + for (int i = 0; i < this->services_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->services(i).data(), this->services(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(1, this->services(i), target); + } + + // repeated .google.protobuf.FileDescriptorProto files = 2; + for (int i = 0; i < this->files_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->files(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ListServiceResponse::ByteSize() const { + int total_size = 0; + + // repeated string services = 1; + total_size += 1 * this->services_size(); + for (int i = 0; i < this->services_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->services(i)); + } + + // repeated .google.protobuf.FileDescriptorProto files = 2; + total_size += 1 * this->files_size(); + for (int i = 0; i < this->files_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->files(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ListServiceResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ListServiceResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ListServiceResponse::MergeFrom(const ListServiceResponse& from) { + GOOGLE_CHECK_NE(&from, this); + services_.MergeFrom(from.services_); + files_.MergeFrom(from.files_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ListServiceResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ListServiceResponse::CopyFrom(const ListServiceResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ListServiceResponse::IsInitialized() const { + + for (int i = 0; i < files_size(); i++) { + if (!this->files(i).IsInitialized()) return false; + } + return true; +} + +void ListServiceResponse::Swap(ListServiceResponse* other) { + if (other != this) { + services_.Swap(&other->services_); + files_.Swap(&other->files_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ListServiceResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ListServiceResponse_descriptor_; + metadata.reflection = ListServiceResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int MethodStat::kMethodNameFieldNumber; +const int MethodStat::kSucceedCountFieldNumber; +const int MethodStat::kSucceedAvgTimeUsFieldNumber; +const int MethodStat::kSucceedMaxTimeUsFieldNumber; +const int MethodStat::kFailedCountFieldNumber; +const int MethodStat::kFailedAvgTimeUsFieldNumber; +const int MethodStat::kFailedMaxTimeUsFieldNumber; +#endif // !_MSC_VER + +MethodStat::MethodStat() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void MethodStat::InitAsDefaultInstance() { +} + +MethodStat::MethodStat(const MethodStat& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void MethodStat::SharedCtor() { + _cached_size_ = 0; + method_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + succeed_count_ = GOOGLE_LONGLONG(0); + succeed_avg_time_us_ = 0; + succeed_max_time_us_ = GOOGLE_LONGLONG(0); + failed_count_ = GOOGLE_LONGLONG(0); + failed_avg_time_us_ = 0; + failed_max_time_us_ = GOOGLE_LONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +MethodStat::~MethodStat() { + SharedDtor(); +} + +void MethodStat::SharedDtor() { + if (method_name_ != &::google::protobuf::internal::kEmptyString) { + delete method_name_; + } + if (this != default_instance_) { + } +} + +void MethodStat::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* MethodStat::descriptor() { + protobuf_AssignDescriptorsOnce(); + return MethodStat_descriptor_; +} + +const MethodStat& MethodStat::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); return *default_instance_; +} + +MethodStat* MethodStat::default_instance_ = NULL; + +MethodStat* MethodStat::New() const { + return new MethodStat; +} + +void MethodStat::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_method_name()) { + if (method_name_ != &::google::protobuf::internal::kEmptyString) { + method_name_->clear(); + } + } + succeed_count_ = GOOGLE_LONGLONG(0); + succeed_avg_time_us_ = 0; + succeed_max_time_us_ = GOOGLE_LONGLONG(0); + failed_count_ = GOOGLE_LONGLONG(0); + failed_avg_time_us_ = 0; + failed_max_time_us_ = GOOGLE_LONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool MethodStat::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string method_name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_method_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->method_name().data(), this->method_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_succeed_count; + break; + } + + // optional int64 succeed_count = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_succeed_count: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &succeed_count_))); + set_has_succeed_count(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(29)) goto parse_succeed_avg_time_us; + break; + } + + // optional float succeed_avg_time_us = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_succeed_avg_time_us: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, &succeed_avg_time_us_))); + set_has_succeed_avg_time_us(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(32)) goto parse_succeed_max_time_us; + break; + } + + // optional int64 succeed_max_time_us = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_succeed_max_time_us: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &succeed_max_time_us_))); + set_has_succeed_max_time_us(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(40)) goto parse_failed_count; + break; + } + + // optional int64 failed_count = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_failed_count: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &failed_count_))); + set_has_failed_count(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(53)) goto parse_failed_avg_time_us; + break; + } + + // optional float failed_avg_time_us = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_failed_avg_time_us: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, &failed_avg_time_us_))); + set_has_failed_avg_time_us(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(56)) goto parse_failed_max_time_us; + break; + } + + // optional int64 failed_max_time_us = 7; + case 7: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_failed_max_time_us: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &failed_max_time_us_))); + set_has_failed_max_time_us(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void MethodStat::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional string method_name = 1; + if (has_method_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->method_name().data(), this->method_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->method_name(), output); + } + + // optional int64 succeed_count = 2; + if (has_succeed_count()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(2, this->succeed_count(), output); + } + + // optional float succeed_avg_time_us = 3; + if (has_succeed_avg_time_us()) { + ::google::protobuf::internal::WireFormatLite::WriteFloat(3, this->succeed_avg_time_us(), output); + } + + // optional int64 succeed_max_time_us = 4; + if (has_succeed_max_time_us()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(4, this->succeed_max_time_us(), output); + } + + // optional int64 failed_count = 5; + if (has_failed_count()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(5, this->failed_count(), output); + } + + // optional float failed_avg_time_us = 6; + if (has_failed_avg_time_us()) { + ::google::protobuf::internal::WireFormatLite::WriteFloat(6, this->failed_avg_time_us(), output); + } + + // optional int64 failed_max_time_us = 7; + if (has_failed_max_time_us()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(7, this->failed_max_time_us(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* MethodStat::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional string method_name = 1; + if (has_method_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->method_name().data(), this->method_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->method_name(), target); + } + + // optional int64 succeed_count = 2; + if (has_succeed_count()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(2, this->succeed_count(), target); + } + + // optional float succeed_avg_time_us = 3; + if (has_succeed_avg_time_us()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(3, this->succeed_avg_time_us(), target); + } + + // optional int64 succeed_max_time_us = 4; + if (has_succeed_max_time_us()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(4, this->succeed_max_time_us(), target); + } + + // optional int64 failed_count = 5; + if (has_failed_count()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(5, this->failed_count(), target); + } + + // optional float failed_avg_time_us = 6; + if (has_failed_avg_time_us()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(6, this->failed_avg_time_us(), target); + } + + // optional int64 failed_max_time_us = 7; + if (has_failed_max_time_us()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(7, this->failed_max_time_us(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int MethodStat::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string method_name = 1; + if (has_method_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->method_name()); + } + + // optional int64 succeed_count = 2; + if (has_succeed_count()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->succeed_count()); + } + + // optional float succeed_avg_time_us = 3; + if (has_succeed_avg_time_us()) { + total_size += 1 + 4; + } + + // optional int64 succeed_max_time_us = 4; + if (has_succeed_max_time_us()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->succeed_max_time_us()); + } + + // optional int64 failed_count = 5; + if (has_failed_count()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->failed_count()); + } + + // optional float failed_avg_time_us = 6; + if (has_failed_avg_time_us()) { + total_size += 1 + 4; + } + + // optional int64 failed_max_time_us = 7; + if (has_failed_max_time_us()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->failed_max_time_us()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void MethodStat::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const MethodStat* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void MethodStat::MergeFrom(const MethodStat& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_method_name()) { + set_method_name(from.method_name()); + } + if (from.has_succeed_count()) { + set_succeed_count(from.succeed_count()); + } + if (from.has_succeed_avg_time_us()) { + set_succeed_avg_time_us(from.succeed_avg_time_us()); + } + if (from.has_succeed_max_time_us()) { + set_succeed_max_time_us(from.succeed_max_time_us()); + } + if (from.has_failed_count()) { + set_failed_count(from.failed_count()); + } + if (from.has_failed_avg_time_us()) { + set_failed_avg_time_us(from.failed_avg_time_us()); + } + if (from.has_failed_max_time_us()) { + set_failed_max_time_us(from.failed_max_time_us()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void MethodStat::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void MethodStat::CopyFrom(const MethodStat& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool MethodStat::IsInitialized() const { + + return true; +} + +void MethodStat::Swap(MethodStat* other) { + if (other != this) { + std::swap(method_name_, other->method_name_); + std::swap(succeed_count_, other->succeed_count_); + std::swap(succeed_avg_time_us_, other->succeed_avg_time_us_); + std::swap(succeed_max_time_us_, other->succeed_max_time_us_); + std::swap(failed_count_, other->failed_count_); + std::swap(failed_avg_time_us_, other->failed_avg_time_us_); + std::swap(failed_max_time_us_, other->failed_max_time_us_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata MethodStat::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = MethodStat_descriptor_; + metadata.reflection = MethodStat_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ServiceStat::kServiceNameFieldNumber; +const int ServiceStat::kPeriodSecondsFieldNumber; +const int ServiceStat::kSucceedCountFieldNumber; +const int ServiceStat::kFailedCountFieldNumber; +const int ServiceStat::kMethodStatsFieldNumber; +#endif // !_MSC_VER + +ServiceStat::ServiceStat() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ServiceStat::InitAsDefaultInstance() { +} + +ServiceStat::ServiceStat(const ServiceStat& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ServiceStat::SharedCtor() { + _cached_size_ = 0; + service_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + period_seconds_ = GOOGLE_LONGLONG(0); + succeed_count_ = GOOGLE_LONGLONG(0); + failed_count_ = GOOGLE_LONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ServiceStat::~ServiceStat() { + SharedDtor(); +} + +void ServiceStat::SharedDtor() { + if (service_name_ != &::google::protobuf::internal::kEmptyString) { + delete service_name_; + } + if (this != default_instance_) { + } +} + +void ServiceStat::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ServiceStat::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ServiceStat_descriptor_; +} + +const ServiceStat& ServiceStat::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); return *default_instance_; +} + +ServiceStat* ServiceStat::default_instance_ = NULL; + +ServiceStat* ServiceStat::New() const { + return new ServiceStat; +} + +void ServiceStat::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_service_name()) { + if (service_name_ != &::google::protobuf::internal::kEmptyString) { + service_name_->clear(); + } + } + period_seconds_ = GOOGLE_LONGLONG(0); + succeed_count_ = GOOGLE_LONGLONG(0); + failed_count_ = GOOGLE_LONGLONG(0); + } + method_stats_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ServiceStat::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string service_name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_service_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->service_name().data(), this->service_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_period_seconds; + break; + } + + // optional int64 period_seconds = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_period_seconds: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &period_seconds_))); + set_has_period_seconds(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(24)) goto parse_succeed_count; + break; + } + + // optional int64 succeed_count = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_succeed_count: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &succeed_count_))); + set_has_succeed_count(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(32)) goto parse_failed_count; + break; + } + + // optional int64 failed_count = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_failed_count: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &failed_count_))); + set_has_failed_count(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(42)) goto parse_method_stats; + break; + } + + // repeated .sofa.pbrpc.builtin.MethodStat method_stats = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_method_stats: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_method_stats())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(42)) goto parse_method_stats; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ServiceStat::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional string service_name = 1; + if (has_service_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->service_name().data(), this->service_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->service_name(), output); + } + + // optional int64 period_seconds = 2; + if (has_period_seconds()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(2, this->period_seconds(), output); + } + + // optional int64 succeed_count = 3; + if (has_succeed_count()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(3, this->succeed_count(), output); + } + + // optional int64 failed_count = 4; + if (has_failed_count()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(4, this->failed_count(), output); + } + + // repeated .sofa.pbrpc.builtin.MethodStat method_stats = 5; + for (int i = 0; i < this->method_stats_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 5, this->method_stats(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ServiceStat::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional string service_name = 1; + if (has_service_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->service_name().data(), this->service_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->service_name(), target); + } + + // optional int64 period_seconds = 2; + if (has_period_seconds()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(2, this->period_seconds(), target); + } + + // optional int64 succeed_count = 3; + if (has_succeed_count()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(3, this->succeed_count(), target); + } + + // optional int64 failed_count = 4; + if (has_failed_count()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(4, this->failed_count(), target); + } + + // repeated .sofa.pbrpc.builtin.MethodStat method_stats = 5; + for (int i = 0; i < this->method_stats_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 5, this->method_stats(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ServiceStat::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string service_name = 1; + if (has_service_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->service_name()); + } + + // optional int64 period_seconds = 2; + if (has_period_seconds()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->period_seconds()); + } + + // optional int64 succeed_count = 3; + if (has_succeed_count()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->succeed_count()); + } + + // optional int64 failed_count = 4; + if (has_failed_count()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->failed_count()); + } + + } + // repeated .sofa.pbrpc.builtin.MethodStat method_stats = 5; + total_size += 1 * this->method_stats_size(); + for (int i = 0; i < this->method_stats_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->method_stats(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ServiceStat::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ServiceStat* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ServiceStat::MergeFrom(const ServiceStat& from) { + GOOGLE_CHECK_NE(&from, this); + method_stats_.MergeFrom(from.method_stats_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_service_name()) { + set_service_name(from.service_name()); + } + if (from.has_period_seconds()) { + set_period_seconds(from.period_seconds()); + } + if (from.has_succeed_count()) { + set_succeed_count(from.succeed_count()); + } + if (from.has_failed_count()) { + set_failed_count(from.failed_count()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ServiceStat::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ServiceStat::CopyFrom(const ServiceStat& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ServiceStat::IsInitialized() const { + + return true; +} + +void ServiceStat::Swap(ServiceStat* other) { + if (other != this) { + std::swap(service_name_, other->service_name_); + std::swap(period_seconds_, other->period_seconds_); + std::swap(succeed_count_, other->succeed_count_); + std::swap(failed_count_, other->failed_count_); + method_stats_.Swap(&other->method_stats_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ServiceStat::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ServiceStat_descriptor_; + metadata.reflection = ServiceStat_reflection_; + return metadata; +} + + +// =================================================================== + +const ::std::string StatRequest::_default_service_name_("all"); +#ifndef _MSC_VER +const int StatRequest::kServiceNameFieldNumber; +const int StatRequest::kPeriodSecondsFieldNumber; +#endif // !_MSC_VER + +StatRequest::StatRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void StatRequest::InitAsDefaultInstance() { +} + +StatRequest::StatRequest(const StatRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void StatRequest::SharedCtor() { + _cached_size_ = 0; + service_name_ = const_cast< ::std::string*>(&_default_service_name_); + period_seconds_ = GOOGLE_LONGLONG(60); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +StatRequest::~StatRequest() { + SharedDtor(); +} + +void StatRequest::SharedDtor() { + if (service_name_ != &_default_service_name_) { + delete service_name_; + } + if (this != default_instance_) { + } +} + +void StatRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* StatRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return StatRequest_descriptor_; +} + +const StatRequest& StatRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); return *default_instance_; +} + +StatRequest* StatRequest::default_instance_ = NULL; + +StatRequest* StatRequest::New() const { + return new StatRequest; +} + +void StatRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_service_name()) { + if (service_name_ != &_default_service_name_) { + service_name_->assign(_default_service_name_); + } + } + period_seconds_ = GOOGLE_LONGLONG(60); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool StatRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string service_name = 1 [default = "all"]; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_service_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->service_name().data(), this->service_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_period_seconds; + break; + } + + // optional int64 period_seconds = 2 [default = 60]; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_period_seconds: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &period_seconds_))); + set_has_period_seconds(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void StatRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional string service_name = 1 [default = "all"]; + if (has_service_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->service_name().data(), this->service_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->service_name(), output); + } + + // optional int64 period_seconds = 2 [default = 60]; + if (has_period_seconds()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(2, this->period_seconds(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* StatRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional string service_name = 1 [default = "all"]; + if (has_service_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->service_name().data(), this->service_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->service_name(), target); + } + + // optional int64 period_seconds = 2 [default = 60]; + if (has_period_seconds()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(2, this->period_seconds(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int StatRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string service_name = 1 [default = "all"]; + if (has_service_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->service_name()); + } + + // optional int64 period_seconds = 2 [default = 60]; + if (has_period_seconds()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->period_seconds()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void StatRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const StatRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void StatRequest::MergeFrom(const StatRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_service_name()) { + set_service_name(from.service_name()); + } + if (from.has_period_seconds()) { + set_period_seconds(from.period_seconds()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void StatRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void StatRequest::CopyFrom(const StatRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool StatRequest::IsInitialized() const { + + return true; +} + +void StatRequest::Swap(StatRequest* other) { + if (other != this) { + std::swap(service_name_, other->service_name_); + std::swap(period_seconds_, other->period_seconds_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata StatRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = StatRequest_descriptor_; + metadata.reflection = StatRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int StatResponse::kServiceStatsFieldNumber; +#endif // !_MSC_VER + +StatResponse::StatResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void StatResponse::InitAsDefaultInstance() { +} + +StatResponse::StatResponse(const StatResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void StatResponse::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +StatResponse::~StatResponse() { + SharedDtor(); +} + +void StatResponse::SharedDtor() { + if (this != default_instance_) { + } +} + +void StatResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* StatResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return StatResponse_descriptor_; +} + +const StatResponse& StatResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); return *default_instance_; +} + +StatResponse* StatResponse::default_instance_ = NULL; + +StatResponse* StatResponse::New() const { + return new StatResponse; +} + +void StatResponse::Clear() { + service_stats_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool StatResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .sofa.pbrpc.builtin.ServiceStat service_stats = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_service_stats: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_service_stats())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_service_stats; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void StatResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated .sofa.pbrpc.builtin.ServiceStat service_stats = 1; + for (int i = 0; i < this->service_stats_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->service_stats(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* StatResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated .sofa.pbrpc.builtin.ServiceStat service_stats = 1; + for (int i = 0; i < this->service_stats_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->service_stats(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int StatResponse::ByteSize() const { + int total_size = 0; + + // repeated .sofa.pbrpc.builtin.ServiceStat service_stats = 1; + total_size += 1 * this->service_stats_size(); + for (int i = 0; i < this->service_stats_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->service_stats(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void StatResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const StatResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void StatResponse::MergeFrom(const StatResponse& from) { + GOOGLE_CHECK_NE(&from, this); + service_stats_.MergeFrom(from.service_stats_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void StatResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void StatResponse::CopyFrom(const StatResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool StatResponse::IsInitialized() const { + + return true; +} + +void StatResponse::Swap(StatResponse* other) { + if (other != this) { + service_stats_.Swap(&other->service_stats_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata StatResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = StatResponse_descriptor_; + metadata.reflection = StatResponse_reflection_; + return metadata; +} + + +// =================================================================== + +BuiltinService::~BuiltinService() {} + +const ::google::protobuf::ServiceDescriptor* BuiltinService::descriptor() { + protobuf_AssignDescriptorsOnce(); + return BuiltinService_descriptor_; +} + +const ::google::protobuf::ServiceDescriptor* BuiltinService::GetDescriptor() { + protobuf_AssignDescriptorsOnce(); + return BuiltinService_descriptor_; +} + +void BuiltinService::Health(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::HealthRequest*, + ::sofa::pbrpc::builtin::HealthResponse*, + ::google::protobuf::Closure* done) { + controller->SetFailed("Method Health() not implemented."); + done->Run(); +} + +void BuiltinService::ServerOptions(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::ServerOptionsRequest*, + ::sofa::pbrpc::builtin::ServerOptionsResponse*, + ::google::protobuf::Closure* done) { + controller->SetFailed("Method ServerOptions() not implemented."); + done->Run(); +} + +void BuiltinService::UpdateOptions(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::UpdateOptionsRequest*, + ::sofa::pbrpc::builtin::UpdateOptionsResponse*, + ::google::protobuf::Closure* done) { + controller->SetFailed("Method UpdateOptions() not implemented."); + done->Run(); +} + +void BuiltinService::ServerStatus(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::ServerStatusRequest*, + ::sofa::pbrpc::builtin::ServerStatusResponse*, + ::google::protobuf::Closure* done) { + controller->SetFailed("Method ServerStatus() not implemented."); + done->Run(); +} + +void BuiltinService::ListService(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::ListServiceRequest*, + ::sofa::pbrpc::builtin::ListServiceResponse*, + ::google::protobuf::Closure* done) { + controller->SetFailed("Method ListService() not implemented."); + done->Run(); +} + +void BuiltinService::Stat(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::StatRequest*, + ::sofa::pbrpc::builtin::StatResponse*, + ::google::protobuf::Closure* done) { + controller->SetFailed("Method Stat() not implemented."); + done->Run(); +} + +void BuiltinService::CallMethod(const ::google::protobuf::MethodDescriptor* method, + ::google::protobuf::RpcController* controller, + const ::google::protobuf::Message* request, + ::google::protobuf::Message* response, + ::google::protobuf::Closure* done) { + GOOGLE_DCHECK_EQ(method->service(), BuiltinService_descriptor_); + switch(method->index()) { + case 0: + Health(controller, + ::google::protobuf::down_cast(request), + ::google::protobuf::down_cast< ::sofa::pbrpc::builtin::HealthResponse*>(response), + done); + break; + case 1: + ServerOptions(controller, + ::google::protobuf::down_cast(request), + ::google::protobuf::down_cast< ::sofa::pbrpc::builtin::ServerOptionsResponse*>(response), + done); + break; + case 2: + UpdateOptions(controller, + ::google::protobuf::down_cast(request), + ::google::protobuf::down_cast< ::sofa::pbrpc::builtin::UpdateOptionsResponse*>(response), + done); + break; + case 3: + ServerStatus(controller, + ::google::protobuf::down_cast(request), + ::google::protobuf::down_cast< ::sofa::pbrpc::builtin::ServerStatusResponse*>(response), + done); + break; + case 4: + ListService(controller, + ::google::protobuf::down_cast(request), + ::google::protobuf::down_cast< ::sofa::pbrpc::builtin::ListServiceResponse*>(response), + done); + break; + case 5: + Stat(controller, + ::google::protobuf::down_cast(request), + ::google::protobuf::down_cast< ::sofa::pbrpc::builtin::StatResponse*>(response), + done); + break; + default: + GOOGLE_LOG(FATAL) << "Bad method index; this should never happen."; + break; + } +} + +const ::google::protobuf::Message& BuiltinService::GetRequestPrototype( + const ::google::protobuf::MethodDescriptor* method) const { + GOOGLE_DCHECK_EQ(method->service(), descriptor()); + switch(method->index()) { + case 0: + return ::sofa::pbrpc::builtin::HealthRequest::default_instance(); + case 1: + return ::sofa::pbrpc::builtin::ServerOptionsRequest::default_instance(); + case 2: + return ::sofa::pbrpc::builtin::UpdateOptionsRequest::default_instance(); + case 3: + return ::sofa::pbrpc::builtin::ServerStatusRequest::default_instance(); + case 4: + return ::sofa::pbrpc::builtin::ListServiceRequest::default_instance(); + case 5: + return ::sofa::pbrpc::builtin::StatRequest::default_instance(); + default: + GOOGLE_LOG(FATAL) << "Bad method index; this should never happen."; + return *reinterpret_cast< ::google::protobuf::Message*>(NULL); + } +} + +const ::google::protobuf::Message& BuiltinService::GetResponsePrototype( + const ::google::protobuf::MethodDescriptor* method) const { + GOOGLE_DCHECK_EQ(method->service(), descriptor()); + switch(method->index()) { + case 0: + return ::sofa::pbrpc::builtin::HealthResponse::default_instance(); + case 1: + return ::sofa::pbrpc::builtin::ServerOptionsResponse::default_instance(); + case 2: + return ::sofa::pbrpc::builtin::UpdateOptionsResponse::default_instance(); + case 3: + return ::sofa::pbrpc::builtin::ServerStatusResponse::default_instance(); + case 4: + return ::sofa::pbrpc::builtin::ListServiceResponse::default_instance(); + case 5: + return ::sofa::pbrpc::builtin::StatResponse::default_instance(); + default: + GOOGLE_LOG(FATAL) << "Bad method index; this should never happen."; + return *reinterpret_cast< ::google::protobuf::Message*>(NULL); + } +} + +BuiltinService_Stub::BuiltinService_Stub(::google::protobuf::RpcChannel* channel) + : channel_(channel), owns_channel_(false) {} +BuiltinService_Stub::BuiltinService_Stub( + ::google::protobuf::RpcChannel* channel, + ::google::protobuf::Service::ChannelOwnership ownership) + : channel_(channel), + owns_channel_(ownership == ::google::protobuf::Service::STUB_OWNS_CHANNEL) {} +BuiltinService_Stub::~BuiltinService_Stub() { + if (owns_channel_) delete channel_; +} + +void BuiltinService_Stub::Health(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::HealthRequest* request, + ::sofa::pbrpc::builtin::HealthResponse* response, + ::google::protobuf::Closure* done) { + channel_->CallMethod(descriptor()->method(0), + controller, request, response, done); +} +void BuiltinService_Stub::ServerOptions(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::ServerOptionsRequest* request, + ::sofa::pbrpc::builtin::ServerOptionsResponse* response, + ::google::protobuf::Closure* done) { + channel_->CallMethod(descriptor()->method(1), + controller, request, response, done); +} +void BuiltinService_Stub::UpdateOptions(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::UpdateOptionsRequest* request, + ::sofa::pbrpc::builtin::UpdateOptionsResponse* response, + ::google::protobuf::Closure* done) { + channel_->CallMethod(descriptor()->method(2), + controller, request, response, done); +} +void BuiltinService_Stub::ServerStatus(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::ServerStatusRequest* request, + ::sofa::pbrpc::builtin::ServerStatusResponse* response, + ::google::protobuf::Closure* done) { + channel_->CallMethod(descriptor()->method(3), + controller, request, response, done); +} +void BuiltinService_Stub::ListService(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::ListServiceRequest* request, + ::sofa::pbrpc::builtin::ListServiceResponse* response, + ::google::protobuf::Closure* done) { + channel_->CallMethod(descriptor()->method(4), + controller, request, response, done); +} +void BuiltinService_Stub::Stat(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::StatRequest* request, + ::sofa::pbrpc::builtin::StatResponse* response, + ::google::protobuf::Closure* done) { + channel_->CallMethod(descriptor()->method(5), + controller, request, response, done); +} + +// @@protoc_insertion_point(namespace_scope) + +} // namespace builtin +} // namespace pbrpc +} // namespace sofa + +// @@protoc_insertion_point(global_scope) diff --git a/src/sofa/pbrpc/builtin_service.pb.h b/src/sofa/pbrpc/builtin_service.pb.h new file mode 100644 index 0000000..d7d9dad --- /dev/null +++ b/src/sofa/pbrpc/builtin_service.pb.h @@ -0,0 +1,2636 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: sofa/pbrpc/builtin_service.proto + +#ifndef PROTOBUF_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto__INCLUDED +#define PROTOBUF_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2004000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2004001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include "google/protobuf/descriptor.pb.h" +#include "sofa/pbrpc/rpc_option.pb.h" +// @@protoc_insertion_point(includes) + +namespace sofa { +namespace pbrpc { +namespace builtin { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); +void protobuf_AssignDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); +void protobuf_ShutdownFile_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + +class HealthRequest; +class HealthResponse; +class ServerOptions; +class ServerOptionsRequest; +class ServerOptionsResponse; +class UpdateOptionsRequest; +class UpdateOptionsResponse; +class ServerStatusRequest; +class ServerStatusResponse; +class ListServiceRequest; +class ListServiceResponse; +class MethodStat; +class ServiceStat; +class StatRequest; +class StatResponse; + +// =================================================================== + +class HealthRequest : public ::google::protobuf::Message { + public: + HealthRequest(); + virtual ~HealthRequest(); + + HealthRequest(const HealthRequest& from); + + inline HealthRequest& operator=(const HealthRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const HealthRequest& default_instance(); + + void Swap(HealthRequest* other); + + // implements Message ---------------------------------------------- + + HealthRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const HealthRequest& from); + void MergeFrom(const HealthRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // @@protoc_insertion_point(class_scope:sofa.pbrpc.builtin.HealthRequest) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[1]; + + friend void protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_AssignDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_ShutdownFile_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + + void InitAsDefaultInstance(); + static HealthRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class HealthResponse : public ::google::protobuf::Message { + public: + HealthResponse(); + virtual ~HealthResponse(); + + HealthResponse(const HealthResponse& from); + + inline HealthResponse& operator=(const HealthResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const HealthResponse& default_instance(); + + void Swap(HealthResponse* other); + + // implements Message ---------------------------------------------- + + HealthResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const HealthResponse& from); + void MergeFrom(const HealthResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string health = 1; + inline bool has_health() const; + inline void clear_health(); + static const int kHealthFieldNumber = 1; + inline const ::std::string& health() const; + inline void set_health(const ::std::string& value); + inline void set_health(const char* value); + inline void set_health(const char* value, size_t size); + inline ::std::string* mutable_health(); + inline ::std::string* release_health(); + + // @@protoc_insertion_point(class_scope:sofa.pbrpc.builtin.HealthResponse) + private: + inline void set_has_health(); + inline void clear_has_health(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* health_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_AssignDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_ShutdownFile_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + + void InitAsDefaultInstance(); + static HealthResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class ServerOptions : public ::google::protobuf::Message { + public: + ServerOptions(); + virtual ~ServerOptions(); + + ServerOptions(const ServerOptions& from); + + inline ServerOptions& operator=(const ServerOptions& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ServerOptions& default_instance(); + + void Swap(ServerOptions* other); + + // implements Message ---------------------------------------------- + + ServerOptions* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ServerOptions& from); + void MergeFrom(const ServerOptions& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int64 work_thread_num = 1; + inline bool has_work_thread_num() const; + inline void clear_work_thread_num(); + static const int kWorkThreadNumFieldNumber = 1; + inline ::google::protobuf::int64 work_thread_num() const; + inline void set_work_thread_num(::google::protobuf::int64 value); + + // optional int64 keep_alive_time = 2; + inline bool has_keep_alive_time() const; + inline void clear_keep_alive_time(); + static const int kKeepAliveTimeFieldNumber = 2; + inline ::google::protobuf::int64 keep_alive_time() const; + inline void set_keep_alive_time(::google::protobuf::int64 value); + + // optional int64 max_pending_buffer_size = 3; + inline bool has_max_pending_buffer_size() const; + inline void clear_max_pending_buffer_size(); + static const int kMaxPendingBufferSizeFieldNumber = 3; + inline ::google::protobuf::int64 max_pending_buffer_size() const; + inline void set_max_pending_buffer_size(::google::protobuf::int64 value); + + // optional int64 max_throughput_in = 4; + inline bool has_max_throughput_in() const; + inline void clear_max_throughput_in(); + static const int kMaxThroughputInFieldNumber = 4; + inline ::google::protobuf::int64 max_throughput_in() const; + inline void set_max_throughput_in(::google::protobuf::int64 value); + + // optional int64 max_throughput_out = 5; + inline bool has_max_throughput_out() const; + inline void clear_max_throughput_out(); + static const int kMaxThroughputOutFieldNumber = 5; + inline ::google::protobuf::int64 max_throughput_out() const; + inline void set_max_throughput_out(::google::protobuf::int64 value); + + // optional bool disable_builtin_services = 6; + inline bool has_disable_builtin_services() const; + inline void clear_disable_builtin_services(); + static const int kDisableBuiltinServicesFieldNumber = 6; + inline bool disable_builtin_services() const; + inline void set_disable_builtin_services(bool value); + + // optional bool disable_list_service = 7; + inline bool has_disable_list_service() const; + inline void clear_disable_list_service(); + static const int kDisableListServiceFieldNumber = 7; + inline bool disable_list_service() const; + inline void set_disable_list_service(bool value); + + // @@protoc_insertion_point(class_scope:sofa.pbrpc.builtin.ServerOptions) + private: + inline void set_has_work_thread_num(); + inline void clear_has_work_thread_num(); + inline void set_has_keep_alive_time(); + inline void clear_has_keep_alive_time(); + inline void set_has_max_pending_buffer_size(); + inline void clear_has_max_pending_buffer_size(); + inline void set_has_max_throughput_in(); + inline void clear_has_max_throughput_in(); + inline void set_has_max_throughput_out(); + inline void clear_has_max_throughput_out(); + inline void set_has_disable_builtin_services(); + inline void clear_has_disable_builtin_services(); + inline void set_has_disable_list_service(); + inline void clear_has_disable_list_service(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::int64 work_thread_num_; + ::google::protobuf::int64 keep_alive_time_; + ::google::protobuf::int64 max_pending_buffer_size_; + ::google::protobuf::int64 max_throughput_in_; + ::google::protobuf::int64 max_throughput_out_; + bool disable_builtin_services_; + bool disable_list_service_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32]; + + friend void protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_AssignDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_ShutdownFile_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + + void InitAsDefaultInstance(); + static ServerOptions* default_instance_; +}; +// ------------------------------------------------------------------- + +class ServerOptionsRequest : public ::google::protobuf::Message { + public: + ServerOptionsRequest(); + virtual ~ServerOptionsRequest(); + + ServerOptionsRequest(const ServerOptionsRequest& from); + + inline ServerOptionsRequest& operator=(const ServerOptionsRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ServerOptionsRequest& default_instance(); + + void Swap(ServerOptionsRequest* other); + + // implements Message ---------------------------------------------- + + ServerOptionsRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ServerOptionsRequest& from); + void MergeFrom(const ServerOptionsRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // @@protoc_insertion_point(class_scope:sofa.pbrpc.builtin.ServerOptionsRequest) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[1]; + + friend void protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_AssignDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_ShutdownFile_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + + void InitAsDefaultInstance(); + static ServerOptionsRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class ServerOptionsResponse : public ::google::protobuf::Message { + public: + ServerOptionsResponse(); + virtual ~ServerOptionsResponse(); + + ServerOptionsResponse(const ServerOptionsResponse& from); + + inline ServerOptionsResponse& operator=(const ServerOptionsResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ServerOptionsResponse& default_instance(); + + void Swap(ServerOptionsResponse* other); + + // implements Message ---------------------------------------------- + + ServerOptionsResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ServerOptionsResponse& from); + void MergeFrom(const ServerOptionsResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional .sofa.pbrpc.builtin.ServerOptions options = 1; + inline bool has_options() const; + inline void clear_options(); + static const int kOptionsFieldNumber = 1; + inline const ::sofa::pbrpc::builtin::ServerOptions& options() const; + inline ::sofa::pbrpc::builtin::ServerOptions* mutable_options(); + inline ::sofa::pbrpc::builtin::ServerOptions* release_options(); + + // @@protoc_insertion_point(class_scope:sofa.pbrpc.builtin.ServerOptionsResponse) + private: + inline void set_has_options(); + inline void clear_has_options(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::sofa::pbrpc::builtin::ServerOptions* options_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_AssignDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_ShutdownFile_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + + void InitAsDefaultInstance(); + static ServerOptionsResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class UpdateOptionsRequest : public ::google::protobuf::Message { + public: + UpdateOptionsRequest(); + virtual ~UpdateOptionsRequest(); + + UpdateOptionsRequest(const UpdateOptionsRequest& from); + + inline UpdateOptionsRequest& operator=(const UpdateOptionsRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const UpdateOptionsRequest& default_instance(); + + void Swap(UpdateOptionsRequest* other); + + // implements Message ---------------------------------------------- + + UpdateOptionsRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const UpdateOptionsRequest& from); + void MergeFrom(const UpdateOptionsRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional .sofa.pbrpc.builtin.ServerOptions options = 1; + inline bool has_options() const; + inline void clear_options(); + static const int kOptionsFieldNumber = 1; + inline const ::sofa::pbrpc::builtin::ServerOptions& options() const; + inline ::sofa::pbrpc::builtin::ServerOptions* mutable_options(); + inline ::sofa::pbrpc::builtin::ServerOptions* release_options(); + + // @@protoc_insertion_point(class_scope:sofa.pbrpc.builtin.UpdateOptionsRequest) + private: + inline void set_has_options(); + inline void clear_has_options(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::sofa::pbrpc::builtin::ServerOptions* options_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_AssignDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_ShutdownFile_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + + void InitAsDefaultInstance(); + static UpdateOptionsRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class UpdateOptionsResponse : public ::google::protobuf::Message { + public: + UpdateOptionsResponse(); + virtual ~UpdateOptionsResponse(); + + UpdateOptionsResponse(const UpdateOptionsResponse& from); + + inline UpdateOptionsResponse& operator=(const UpdateOptionsResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const UpdateOptionsResponse& default_instance(); + + void Swap(UpdateOptionsResponse* other); + + // implements Message ---------------------------------------------- + + UpdateOptionsResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const UpdateOptionsResponse& from); + void MergeFrom(const UpdateOptionsResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional .sofa.pbrpc.builtin.ServerOptions options = 1; + inline bool has_options() const; + inline void clear_options(); + static const int kOptionsFieldNumber = 1; + inline const ::sofa::pbrpc::builtin::ServerOptions& options() const; + inline ::sofa::pbrpc::builtin::ServerOptions* mutable_options(); + inline ::sofa::pbrpc::builtin::ServerOptions* release_options(); + + // @@protoc_insertion_point(class_scope:sofa.pbrpc.builtin.UpdateOptionsResponse) + private: + inline void set_has_options(); + inline void clear_has_options(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::sofa::pbrpc::builtin::ServerOptions* options_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_AssignDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_ShutdownFile_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + + void InitAsDefaultInstance(); + static UpdateOptionsResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class ServerStatusRequest : public ::google::protobuf::Message { + public: + ServerStatusRequest(); + virtual ~ServerStatusRequest(); + + ServerStatusRequest(const ServerStatusRequest& from); + + inline ServerStatusRequest& operator=(const ServerStatusRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ServerStatusRequest& default_instance(); + + void Swap(ServerStatusRequest* other); + + // implements Message ---------------------------------------------- + + ServerStatusRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ServerStatusRequest& from); + void MergeFrom(const ServerStatusRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // @@protoc_insertion_point(class_scope:sofa.pbrpc.builtin.ServerStatusRequest) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[1]; + + friend void protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_AssignDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_ShutdownFile_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + + void InitAsDefaultInstance(); + static ServerStatusRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class ServerStatusResponse : public ::google::protobuf::Message { + public: + ServerStatusResponse(); + virtual ~ServerStatusResponse(); + + ServerStatusResponse(const ServerStatusResponse& from); + + inline ServerStatusResponse& operator=(const ServerStatusResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ServerStatusResponse& default_instance(); + + void Swap(ServerStatusResponse* other); + + // implements Message ---------------------------------------------- + + ServerStatusResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ServerStatusResponse& from); + void MergeFrom(const ServerStatusResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional bool is_listening = 1; + inline bool has_is_listening() const; + inline void clear_is_listening(); + static const int kIsListeningFieldNumber = 1; + inline bool is_listening() const; + inline void set_is_listening(bool value); + + // optional int64 connection_count = 2; + inline bool has_connection_count() const; + inline void clear_connection_count(); + static const int kConnectionCountFieldNumber = 2; + inline ::google::protobuf::int64 connection_count() const; + inline void set_connection_count(::google::protobuf::int64 value); + + // optional int64 service_count = 3; + inline bool has_service_count() const; + inline void clear_service_count(); + static const int kServiceCountFieldNumber = 3; + inline ::google::protobuf::int64 service_count() const; + inline void set_service_count(::google::protobuf::int64 value); + + // optional int64 pending_message_count = 4; + inline bool has_pending_message_count() const; + inline void clear_pending_message_count(); + static const int kPendingMessageCountFieldNumber = 4; + inline ::google::protobuf::int64 pending_message_count() const; + inline void set_pending_message_count(::google::protobuf::int64 value); + + // optional int64 pending_buffer_size = 5; + inline bool has_pending_buffer_size() const; + inline void clear_pending_buffer_size(); + static const int kPendingBufferSizeFieldNumber = 5; + inline ::google::protobuf::int64 pending_buffer_size() const; + inline void set_pending_buffer_size(::google::protobuf::int64 value); + + // optional int64 pending_data_size = 6; + inline bool has_pending_data_size() const; + inline void clear_pending_data_size(); + static const int kPendingDataSizeFieldNumber = 6; + inline ::google::protobuf::int64 pending_data_size() const; + inline void set_pending_data_size(::google::protobuf::int64 value); + + // @@protoc_insertion_point(class_scope:sofa.pbrpc.builtin.ServerStatusResponse) + private: + inline void set_has_is_listening(); + inline void clear_has_is_listening(); + inline void set_has_connection_count(); + inline void clear_has_connection_count(); + inline void set_has_service_count(); + inline void clear_has_service_count(); + inline void set_has_pending_message_count(); + inline void clear_has_pending_message_count(); + inline void set_has_pending_buffer_size(); + inline void clear_has_pending_buffer_size(); + inline void set_has_pending_data_size(); + inline void clear_has_pending_data_size(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::int64 connection_count_; + ::google::protobuf::int64 service_count_; + ::google::protobuf::int64 pending_message_count_; + ::google::protobuf::int64 pending_buffer_size_; + ::google::protobuf::int64 pending_data_size_; + bool is_listening_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(6 + 31) / 32]; + + friend void protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_AssignDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_ShutdownFile_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + + void InitAsDefaultInstance(); + static ServerStatusResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class ListServiceRequest : public ::google::protobuf::Message { + public: + ListServiceRequest(); + virtual ~ListServiceRequest(); + + ListServiceRequest(const ListServiceRequest& from); + + inline ListServiceRequest& operator=(const ListServiceRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ListServiceRequest& default_instance(); + + void Swap(ListServiceRequest* other); + + // implements Message ---------------------------------------------- + + ListServiceRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ListServiceRequest& from); + void MergeFrom(const ListServiceRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // @@protoc_insertion_point(class_scope:sofa.pbrpc.builtin.ListServiceRequest) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[1]; + + friend void protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_AssignDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_ShutdownFile_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + + void InitAsDefaultInstance(); + static ListServiceRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class ListServiceResponse : public ::google::protobuf::Message { + public: + ListServiceResponse(); + virtual ~ListServiceResponse(); + + ListServiceResponse(const ListServiceResponse& from); + + inline ListServiceResponse& operator=(const ListServiceResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ListServiceResponse& default_instance(); + + void Swap(ListServiceResponse* other); + + // implements Message ---------------------------------------------- + + ListServiceResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ListServiceResponse& from); + void MergeFrom(const ListServiceResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated string services = 1; + inline int services_size() const; + inline void clear_services(); + static const int kServicesFieldNumber = 1; + inline const ::std::string& services(int index) const; + inline ::std::string* mutable_services(int index); + inline void set_services(int index, const ::std::string& value); + inline void set_services(int index, const char* value); + inline void set_services(int index, const char* value, size_t size); + inline ::std::string* add_services(); + inline void add_services(const ::std::string& value); + inline void add_services(const char* value); + inline void add_services(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& services() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_services(); + + // repeated .google.protobuf.FileDescriptorProto files = 2; + inline int files_size() const; + inline void clear_files(); + static const int kFilesFieldNumber = 2; + inline const ::google::protobuf::FileDescriptorProto& files(int index) const; + inline ::google::protobuf::FileDescriptorProto* mutable_files(int index); + inline ::google::protobuf::FileDescriptorProto* add_files(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& + files() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* + mutable_files(); + + // @@protoc_insertion_point(class_scope:sofa.pbrpc.builtin.ListServiceResponse) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::std::string> services_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > files_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_AssignDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_ShutdownFile_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + + void InitAsDefaultInstance(); + static ListServiceResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class MethodStat : public ::google::protobuf::Message { + public: + MethodStat(); + virtual ~MethodStat(); + + MethodStat(const MethodStat& from); + + inline MethodStat& operator=(const MethodStat& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const MethodStat& default_instance(); + + void Swap(MethodStat* other); + + // implements Message ---------------------------------------------- + + MethodStat* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const MethodStat& from); + void MergeFrom(const MethodStat& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string method_name = 1; + inline bool has_method_name() const; + inline void clear_method_name(); + static const int kMethodNameFieldNumber = 1; + inline const ::std::string& method_name() const; + inline void set_method_name(const ::std::string& value); + inline void set_method_name(const char* value); + inline void set_method_name(const char* value, size_t size); + inline ::std::string* mutable_method_name(); + inline ::std::string* release_method_name(); + + // optional int64 succeed_count = 2; + inline bool has_succeed_count() const; + inline void clear_succeed_count(); + static const int kSucceedCountFieldNumber = 2; + inline ::google::protobuf::int64 succeed_count() const; + inline void set_succeed_count(::google::protobuf::int64 value); + + // optional float succeed_avg_time_us = 3; + inline bool has_succeed_avg_time_us() const; + inline void clear_succeed_avg_time_us(); + static const int kSucceedAvgTimeUsFieldNumber = 3; + inline float succeed_avg_time_us() const; + inline void set_succeed_avg_time_us(float value); + + // optional int64 succeed_max_time_us = 4; + inline bool has_succeed_max_time_us() const; + inline void clear_succeed_max_time_us(); + static const int kSucceedMaxTimeUsFieldNumber = 4; + inline ::google::protobuf::int64 succeed_max_time_us() const; + inline void set_succeed_max_time_us(::google::protobuf::int64 value); + + // optional int64 failed_count = 5; + inline bool has_failed_count() const; + inline void clear_failed_count(); + static const int kFailedCountFieldNumber = 5; + inline ::google::protobuf::int64 failed_count() const; + inline void set_failed_count(::google::protobuf::int64 value); + + // optional float failed_avg_time_us = 6; + inline bool has_failed_avg_time_us() const; + inline void clear_failed_avg_time_us(); + static const int kFailedAvgTimeUsFieldNumber = 6; + inline float failed_avg_time_us() const; + inline void set_failed_avg_time_us(float value); + + // optional int64 failed_max_time_us = 7; + inline bool has_failed_max_time_us() const; + inline void clear_failed_max_time_us(); + static const int kFailedMaxTimeUsFieldNumber = 7; + inline ::google::protobuf::int64 failed_max_time_us() const; + inline void set_failed_max_time_us(::google::protobuf::int64 value); + + // @@protoc_insertion_point(class_scope:sofa.pbrpc.builtin.MethodStat) + private: + inline void set_has_method_name(); + inline void clear_has_method_name(); + inline void set_has_succeed_count(); + inline void clear_has_succeed_count(); + inline void set_has_succeed_avg_time_us(); + inline void clear_has_succeed_avg_time_us(); + inline void set_has_succeed_max_time_us(); + inline void clear_has_succeed_max_time_us(); + inline void set_has_failed_count(); + inline void clear_has_failed_count(); + inline void set_has_failed_avg_time_us(); + inline void clear_has_failed_avg_time_us(); + inline void set_has_failed_max_time_us(); + inline void clear_has_failed_max_time_us(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* method_name_; + ::google::protobuf::int64 succeed_count_; + ::google::protobuf::int64 succeed_max_time_us_; + float succeed_avg_time_us_; + float failed_avg_time_us_; + ::google::protobuf::int64 failed_count_; + ::google::protobuf::int64 failed_max_time_us_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32]; + + friend void protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_AssignDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_ShutdownFile_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + + void InitAsDefaultInstance(); + static MethodStat* default_instance_; +}; +// ------------------------------------------------------------------- + +class ServiceStat : public ::google::protobuf::Message { + public: + ServiceStat(); + virtual ~ServiceStat(); + + ServiceStat(const ServiceStat& from); + + inline ServiceStat& operator=(const ServiceStat& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ServiceStat& default_instance(); + + void Swap(ServiceStat* other); + + // implements Message ---------------------------------------------- + + ServiceStat* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ServiceStat& from); + void MergeFrom(const ServiceStat& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string service_name = 1; + inline bool has_service_name() const; + inline void clear_service_name(); + static const int kServiceNameFieldNumber = 1; + inline const ::std::string& service_name() const; + inline void set_service_name(const ::std::string& value); + inline void set_service_name(const char* value); + inline void set_service_name(const char* value, size_t size); + inline ::std::string* mutable_service_name(); + inline ::std::string* release_service_name(); + + // optional int64 period_seconds = 2; + inline bool has_period_seconds() const; + inline void clear_period_seconds(); + static const int kPeriodSecondsFieldNumber = 2; + inline ::google::protobuf::int64 period_seconds() const; + inline void set_period_seconds(::google::protobuf::int64 value); + + // optional int64 succeed_count = 3; + inline bool has_succeed_count() const; + inline void clear_succeed_count(); + static const int kSucceedCountFieldNumber = 3; + inline ::google::protobuf::int64 succeed_count() const; + inline void set_succeed_count(::google::protobuf::int64 value); + + // optional int64 failed_count = 4; + inline bool has_failed_count() const; + inline void clear_failed_count(); + static const int kFailedCountFieldNumber = 4; + inline ::google::protobuf::int64 failed_count() const; + inline void set_failed_count(::google::protobuf::int64 value); + + // repeated .sofa.pbrpc.builtin.MethodStat method_stats = 5; + inline int method_stats_size() const; + inline void clear_method_stats(); + static const int kMethodStatsFieldNumber = 5; + inline const ::sofa::pbrpc::builtin::MethodStat& method_stats(int index) const; + inline ::sofa::pbrpc::builtin::MethodStat* mutable_method_stats(int index); + inline ::sofa::pbrpc::builtin::MethodStat* add_method_stats(); + inline const ::google::protobuf::RepeatedPtrField< ::sofa::pbrpc::builtin::MethodStat >& + method_stats() const; + inline ::google::protobuf::RepeatedPtrField< ::sofa::pbrpc::builtin::MethodStat >* + mutable_method_stats(); + + // @@protoc_insertion_point(class_scope:sofa.pbrpc.builtin.ServiceStat) + private: + inline void set_has_service_name(); + inline void clear_has_service_name(); + inline void set_has_period_seconds(); + inline void clear_has_period_seconds(); + inline void set_has_succeed_count(); + inline void clear_has_succeed_count(); + inline void set_has_failed_count(); + inline void clear_has_failed_count(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* service_name_; + ::google::protobuf::int64 period_seconds_; + ::google::protobuf::int64 succeed_count_; + ::google::protobuf::int64 failed_count_; + ::google::protobuf::RepeatedPtrField< ::sofa::pbrpc::builtin::MethodStat > method_stats_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(5 + 31) / 32]; + + friend void protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_AssignDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_ShutdownFile_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + + void InitAsDefaultInstance(); + static ServiceStat* default_instance_; +}; +// ------------------------------------------------------------------- + +class StatRequest : public ::google::protobuf::Message { + public: + StatRequest(); + virtual ~StatRequest(); + + StatRequest(const StatRequest& from); + + inline StatRequest& operator=(const StatRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const StatRequest& default_instance(); + + void Swap(StatRequest* other); + + // implements Message ---------------------------------------------- + + StatRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const StatRequest& from); + void MergeFrom(const StatRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string service_name = 1 [default = "all"]; + inline bool has_service_name() const; + inline void clear_service_name(); + static const int kServiceNameFieldNumber = 1; + inline const ::std::string& service_name() const; + inline void set_service_name(const ::std::string& value); + inline void set_service_name(const char* value); + inline void set_service_name(const char* value, size_t size); + inline ::std::string* mutable_service_name(); + inline ::std::string* release_service_name(); + + // optional int64 period_seconds = 2 [default = 60]; + inline bool has_period_seconds() const; + inline void clear_period_seconds(); + static const int kPeriodSecondsFieldNumber = 2; + inline ::google::protobuf::int64 period_seconds() const; + inline void set_period_seconds(::google::protobuf::int64 value); + + // @@protoc_insertion_point(class_scope:sofa.pbrpc.builtin.StatRequest) + private: + inline void set_has_service_name(); + inline void clear_has_service_name(); + inline void set_has_period_seconds(); + inline void clear_has_period_seconds(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* service_name_; + static const ::std::string _default_service_name_; + ::google::protobuf::int64 period_seconds_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_AssignDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_ShutdownFile_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + + void InitAsDefaultInstance(); + static StatRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class StatResponse : public ::google::protobuf::Message { + public: + StatResponse(); + virtual ~StatResponse(); + + StatResponse(const StatResponse& from); + + inline StatResponse& operator=(const StatResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const StatResponse& default_instance(); + + void Swap(StatResponse* other); + + // implements Message ---------------------------------------------- + + StatResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const StatResponse& from); + void MergeFrom(const StatResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .sofa.pbrpc.builtin.ServiceStat service_stats = 1; + inline int service_stats_size() const; + inline void clear_service_stats(); + static const int kServiceStatsFieldNumber = 1; + inline const ::sofa::pbrpc::builtin::ServiceStat& service_stats(int index) const; + inline ::sofa::pbrpc::builtin::ServiceStat* mutable_service_stats(int index); + inline ::sofa::pbrpc::builtin::ServiceStat* add_service_stats(); + inline const ::google::protobuf::RepeatedPtrField< ::sofa::pbrpc::builtin::ServiceStat >& + service_stats() const; + inline ::google::protobuf::RepeatedPtrField< ::sofa::pbrpc::builtin::ServiceStat >* + mutable_service_stats(); + + // @@protoc_insertion_point(class_scope:sofa.pbrpc.builtin.StatResponse) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::sofa::pbrpc::builtin::ServiceStat > service_stats_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_AssignDesc_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + friend void protobuf_ShutdownFile_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto(); + + void InitAsDefaultInstance(); + static StatResponse* default_instance_; +}; +// =================================================================== + +class BuiltinService_Stub; + +class BuiltinService : public ::google::protobuf::Service { + protected: + // This class should be treated as an abstract interface. + inline BuiltinService() {}; + public: + virtual ~BuiltinService(); + + typedef BuiltinService_Stub Stub; + + static const ::google::protobuf::ServiceDescriptor* descriptor(); + + virtual void Health(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::HealthRequest* request, + ::sofa::pbrpc::builtin::HealthResponse* response, + ::google::protobuf::Closure* done); + virtual void ServerOptions(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::ServerOptionsRequest* request, + ::sofa::pbrpc::builtin::ServerOptionsResponse* response, + ::google::protobuf::Closure* done); + virtual void UpdateOptions(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::UpdateOptionsRequest* request, + ::sofa::pbrpc::builtin::UpdateOptionsResponse* response, + ::google::protobuf::Closure* done); + virtual void ServerStatus(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::ServerStatusRequest* request, + ::sofa::pbrpc::builtin::ServerStatusResponse* response, + ::google::protobuf::Closure* done); + virtual void ListService(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::ListServiceRequest* request, + ::sofa::pbrpc::builtin::ListServiceResponse* response, + ::google::protobuf::Closure* done); + virtual void Stat(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::StatRequest* request, + ::sofa::pbrpc::builtin::StatResponse* response, + ::google::protobuf::Closure* done); + + // implements Service ---------------------------------------------- + + const ::google::protobuf::ServiceDescriptor* GetDescriptor(); + void CallMethod(const ::google::protobuf::MethodDescriptor* method, + ::google::protobuf::RpcController* controller, + const ::google::protobuf::Message* request, + ::google::protobuf::Message* response, + ::google::protobuf::Closure* done); + const ::google::protobuf::Message& GetRequestPrototype( + const ::google::protobuf::MethodDescriptor* method) const; + const ::google::protobuf::Message& GetResponsePrototype( + const ::google::protobuf::MethodDescriptor* method) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(BuiltinService); +}; + +class BuiltinService_Stub : public BuiltinService { + public: + BuiltinService_Stub(::google::protobuf::RpcChannel* channel); + BuiltinService_Stub(::google::protobuf::RpcChannel* channel, + ::google::protobuf::Service::ChannelOwnership ownership); + ~BuiltinService_Stub(); + + inline ::google::protobuf::RpcChannel* channel() { return channel_; } + + // implements BuiltinService ------------------------------------------ + + void Health(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::HealthRequest* request, + ::sofa::pbrpc::builtin::HealthResponse* response, + ::google::protobuf::Closure* done); + void ServerOptions(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::ServerOptionsRequest* request, + ::sofa::pbrpc::builtin::ServerOptionsResponse* response, + ::google::protobuf::Closure* done); + void UpdateOptions(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::UpdateOptionsRequest* request, + ::sofa::pbrpc::builtin::UpdateOptionsResponse* response, + ::google::protobuf::Closure* done); + void ServerStatus(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::ServerStatusRequest* request, + ::sofa::pbrpc::builtin::ServerStatusResponse* response, + ::google::protobuf::Closure* done); + void ListService(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::ListServiceRequest* request, + ::sofa::pbrpc::builtin::ListServiceResponse* response, + ::google::protobuf::Closure* done); + void Stat(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::StatRequest* request, + ::sofa::pbrpc::builtin::StatResponse* response, + ::google::protobuf::Closure* done); + private: + ::google::protobuf::RpcChannel* channel_; + bool owns_channel_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(BuiltinService_Stub); +}; + + +// =================================================================== + + +// =================================================================== + +// HealthRequest + +// ------------------------------------------------------------------- + +// HealthResponse + +// optional string health = 1; +inline bool HealthResponse::has_health() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void HealthResponse::set_has_health() { + _has_bits_[0] |= 0x00000001u; +} +inline void HealthResponse::clear_has_health() { + _has_bits_[0] &= ~0x00000001u; +} +inline void HealthResponse::clear_health() { + if (health_ != &::google::protobuf::internal::kEmptyString) { + health_->clear(); + } + clear_has_health(); +} +inline const ::std::string& HealthResponse::health() const { + return *health_; +} +inline void HealthResponse::set_health(const ::std::string& value) { + set_has_health(); + if (health_ == &::google::protobuf::internal::kEmptyString) { + health_ = new ::std::string; + } + health_->assign(value); +} +inline void HealthResponse::set_health(const char* value) { + set_has_health(); + if (health_ == &::google::protobuf::internal::kEmptyString) { + health_ = new ::std::string; + } + health_->assign(value); +} +inline void HealthResponse::set_health(const char* value, size_t size) { + set_has_health(); + if (health_ == &::google::protobuf::internal::kEmptyString) { + health_ = new ::std::string; + } + health_->assign(reinterpret_cast(value), size); +} +inline ::std::string* HealthResponse::mutable_health() { + set_has_health(); + if (health_ == &::google::protobuf::internal::kEmptyString) { + health_ = new ::std::string; + } + return health_; +} +inline ::std::string* HealthResponse::release_health() { + clear_has_health(); + if (health_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = health_; + health_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// ------------------------------------------------------------------- + +// ServerOptions + +// optional int64 work_thread_num = 1; +inline bool ServerOptions::has_work_thread_num() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ServerOptions::set_has_work_thread_num() { + _has_bits_[0] |= 0x00000001u; +} +inline void ServerOptions::clear_has_work_thread_num() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ServerOptions::clear_work_thread_num() { + work_thread_num_ = GOOGLE_LONGLONG(0); + clear_has_work_thread_num(); +} +inline ::google::protobuf::int64 ServerOptions::work_thread_num() const { + return work_thread_num_; +} +inline void ServerOptions::set_work_thread_num(::google::protobuf::int64 value) { + set_has_work_thread_num(); + work_thread_num_ = value; +} + +// optional int64 keep_alive_time = 2; +inline bool ServerOptions::has_keep_alive_time() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void ServerOptions::set_has_keep_alive_time() { + _has_bits_[0] |= 0x00000002u; +} +inline void ServerOptions::clear_has_keep_alive_time() { + _has_bits_[0] &= ~0x00000002u; +} +inline void ServerOptions::clear_keep_alive_time() { + keep_alive_time_ = GOOGLE_LONGLONG(0); + clear_has_keep_alive_time(); +} +inline ::google::protobuf::int64 ServerOptions::keep_alive_time() const { + return keep_alive_time_; +} +inline void ServerOptions::set_keep_alive_time(::google::protobuf::int64 value) { + set_has_keep_alive_time(); + keep_alive_time_ = value; +} + +// optional int64 max_pending_buffer_size = 3; +inline bool ServerOptions::has_max_pending_buffer_size() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void ServerOptions::set_has_max_pending_buffer_size() { + _has_bits_[0] |= 0x00000004u; +} +inline void ServerOptions::clear_has_max_pending_buffer_size() { + _has_bits_[0] &= ~0x00000004u; +} +inline void ServerOptions::clear_max_pending_buffer_size() { + max_pending_buffer_size_ = GOOGLE_LONGLONG(0); + clear_has_max_pending_buffer_size(); +} +inline ::google::protobuf::int64 ServerOptions::max_pending_buffer_size() const { + return max_pending_buffer_size_; +} +inline void ServerOptions::set_max_pending_buffer_size(::google::protobuf::int64 value) { + set_has_max_pending_buffer_size(); + max_pending_buffer_size_ = value; +} + +// optional int64 max_throughput_in = 4; +inline bool ServerOptions::has_max_throughput_in() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void ServerOptions::set_has_max_throughput_in() { + _has_bits_[0] |= 0x00000008u; +} +inline void ServerOptions::clear_has_max_throughput_in() { + _has_bits_[0] &= ~0x00000008u; +} +inline void ServerOptions::clear_max_throughput_in() { + max_throughput_in_ = GOOGLE_LONGLONG(0); + clear_has_max_throughput_in(); +} +inline ::google::protobuf::int64 ServerOptions::max_throughput_in() const { + return max_throughput_in_; +} +inline void ServerOptions::set_max_throughput_in(::google::protobuf::int64 value) { + set_has_max_throughput_in(); + max_throughput_in_ = value; +} + +// optional int64 max_throughput_out = 5; +inline bool ServerOptions::has_max_throughput_out() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void ServerOptions::set_has_max_throughput_out() { + _has_bits_[0] |= 0x00000010u; +} +inline void ServerOptions::clear_has_max_throughput_out() { + _has_bits_[0] &= ~0x00000010u; +} +inline void ServerOptions::clear_max_throughput_out() { + max_throughput_out_ = GOOGLE_LONGLONG(0); + clear_has_max_throughput_out(); +} +inline ::google::protobuf::int64 ServerOptions::max_throughput_out() const { + return max_throughput_out_; +} +inline void ServerOptions::set_max_throughput_out(::google::protobuf::int64 value) { + set_has_max_throughput_out(); + max_throughput_out_ = value; +} + +// optional bool disable_builtin_services = 6; +inline bool ServerOptions::has_disable_builtin_services() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void ServerOptions::set_has_disable_builtin_services() { + _has_bits_[0] |= 0x00000020u; +} +inline void ServerOptions::clear_has_disable_builtin_services() { + _has_bits_[0] &= ~0x00000020u; +} +inline void ServerOptions::clear_disable_builtin_services() { + disable_builtin_services_ = false; + clear_has_disable_builtin_services(); +} +inline bool ServerOptions::disable_builtin_services() const { + return disable_builtin_services_; +} +inline void ServerOptions::set_disable_builtin_services(bool value) { + set_has_disable_builtin_services(); + disable_builtin_services_ = value; +} + +// optional bool disable_list_service = 7; +inline bool ServerOptions::has_disable_list_service() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void ServerOptions::set_has_disable_list_service() { + _has_bits_[0] |= 0x00000040u; +} +inline void ServerOptions::clear_has_disable_list_service() { + _has_bits_[0] &= ~0x00000040u; +} +inline void ServerOptions::clear_disable_list_service() { + disable_list_service_ = false; + clear_has_disable_list_service(); +} +inline bool ServerOptions::disable_list_service() const { + return disable_list_service_; +} +inline void ServerOptions::set_disable_list_service(bool value) { + set_has_disable_list_service(); + disable_list_service_ = value; +} + +// ------------------------------------------------------------------- + +// ServerOptionsRequest + +// ------------------------------------------------------------------- + +// ServerOptionsResponse + +// optional .sofa.pbrpc.builtin.ServerOptions options = 1; +inline bool ServerOptionsResponse::has_options() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ServerOptionsResponse::set_has_options() { + _has_bits_[0] |= 0x00000001u; +} +inline void ServerOptionsResponse::clear_has_options() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ServerOptionsResponse::clear_options() { + if (options_ != NULL) options_->::sofa::pbrpc::builtin::ServerOptions::Clear(); + clear_has_options(); +} +inline const ::sofa::pbrpc::builtin::ServerOptions& ServerOptionsResponse::options() const { + return options_ != NULL ? *options_ : *default_instance_->options_; +} +inline ::sofa::pbrpc::builtin::ServerOptions* ServerOptionsResponse::mutable_options() { + set_has_options(); + if (options_ == NULL) options_ = new ::sofa::pbrpc::builtin::ServerOptions; + return options_; +} +inline ::sofa::pbrpc::builtin::ServerOptions* ServerOptionsResponse::release_options() { + clear_has_options(); + ::sofa::pbrpc::builtin::ServerOptions* temp = options_; + options_ = NULL; + return temp; +} + +// ------------------------------------------------------------------- + +// UpdateOptionsRequest + +// optional .sofa.pbrpc.builtin.ServerOptions options = 1; +inline bool UpdateOptionsRequest::has_options() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void UpdateOptionsRequest::set_has_options() { + _has_bits_[0] |= 0x00000001u; +} +inline void UpdateOptionsRequest::clear_has_options() { + _has_bits_[0] &= ~0x00000001u; +} +inline void UpdateOptionsRequest::clear_options() { + if (options_ != NULL) options_->::sofa::pbrpc::builtin::ServerOptions::Clear(); + clear_has_options(); +} +inline const ::sofa::pbrpc::builtin::ServerOptions& UpdateOptionsRequest::options() const { + return options_ != NULL ? *options_ : *default_instance_->options_; +} +inline ::sofa::pbrpc::builtin::ServerOptions* UpdateOptionsRequest::mutable_options() { + set_has_options(); + if (options_ == NULL) options_ = new ::sofa::pbrpc::builtin::ServerOptions; + return options_; +} +inline ::sofa::pbrpc::builtin::ServerOptions* UpdateOptionsRequest::release_options() { + clear_has_options(); + ::sofa::pbrpc::builtin::ServerOptions* temp = options_; + options_ = NULL; + return temp; +} + +// ------------------------------------------------------------------- + +// UpdateOptionsResponse + +// optional .sofa.pbrpc.builtin.ServerOptions options = 1; +inline bool UpdateOptionsResponse::has_options() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void UpdateOptionsResponse::set_has_options() { + _has_bits_[0] |= 0x00000001u; +} +inline void UpdateOptionsResponse::clear_has_options() { + _has_bits_[0] &= ~0x00000001u; +} +inline void UpdateOptionsResponse::clear_options() { + if (options_ != NULL) options_->::sofa::pbrpc::builtin::ServerOptions::Clear(); + clear_has_options(); +} +inline const ::sofa::pbrpc::builtin::ServerOptions& UpdateOptionsResponse::options() const { + return options_ != NULL ? *options_ : *default_instance_->options_; +} +inline ::sofa::pbrpc::builtin::ServerOptions* UpdateOptionsResponse::mutable_options() { + set_has_options(); + if (options_ == NULL) options_ = new ::sofa::pbrpc::builtin::ServerOptions; + return options_; +} +inline ::sofa::pbrpc::builtin::ServerOptions* UpdateOptionsResponse::release_options() { + clear_has_options(); + ::sofa::pbrpc::builtin::ServerOptions* temp = options_; + options_ = NULL; + return temp; +} + +// ------------------------------------------------------------------- + +// ServerStatusRequest + +// ------------------------------------------------------------------- + +// ServerStatusResponse + +// optional bool is_listening = 1; +inline bool ServerStatusResponse::has_is_listening() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ServerStatusResponse::set_has_is_listening() { + _has_bits_[0] |= 0x00000001u; +} +inline void ServerStatusResponse::clear_has_is_listening() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ServerStatusResponse::clear_is_listening() { + is_listening_ = false; + clear_has_is_listening(); +} +inline bool ServerStatusResponse::is_listening() const { + return is_listening_; +} +inline void ServerStatusResponse::set_is_listening(bool value) { + set_has_is_listening(); + is_listening_ = value; +} + +// optional int64 connection_count = 2; +inline bool ServerStatusResponse::has_connection_count() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void ServerStatusResponse::set_has_connection_count() { + _has_bits_[0] |= 0x00000002u; +} +inline void ServerStatusResponse::clear_has_connection_count() { + _has_bits_[0] &= ~0x00000002u; +} +inline void ServerStatusResponse::clear_connection_count() { + connection_count_ = GOOGLE_LONGLONG(0); + clear_has_connection_count(); +} +inline ::google::protobuf::int64 ServerStatusResponse::connection_count() const { + return connection_count_; +} +inline void ServerStatusResponse::set_connection_count(::google::protobuf::int64 value) { + set_has_connection_count(); + connection_count_ = value; +} + +// optional int64 service_count = 3; +inline bool ServerStatusResponse::has_service_count() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void ServerStatusResponse::set_has_service_count() { + _has_bits_[0] |= 0x00000004u; +} +inline void ServerStatusResponse::clear_has_service_count() { + _has_bits_[0] &= ~0x00000004u; +} +inline void ServerStatusResponse::clear_service_count() { + service_count_ = GOOGLE_LONGLONG(0); + clear_has_service_count(); +} +inline ::google::protobuf::int64 ServerStatusResponse::service_count() const { + return service_count_; +} +inline void ServerStatusResponse::set_service_count(::google::protobuf::int64 value) { + set_has_service_count(); + service_count_ = value; +} + +// optional int64 pending_message_count = 4; +inline bool ServerStatusResponse::has_pending_message_count() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void ServerStatusResponse::set_has_pending_message_count() { + _has_bits_[0] |= 0x00000008u; +} +inline void ServerStatusResponse::clear_has_pending_message_count() { + _has_bits_[0] &= ~0x00000008u; +} +inline void ServerStatusResponse::clear_pending_message_count() { + pending_message_count_ = GOOGLE_LONGLONG(0); + clear_has_pending_message_count(); +} +inline ::google::protobuf::int64 ServerStatusResponse::pending_message_count() const { + return pending_message_count_; +} +inline void ServerStatusResponse::set_pending_message_count(::google::protobuf::int64 value) { + set_has_pending_message_count(); + pending_message_count_ = value; +} + +// optional int64 pending_buffer_size = 5; +inline bool ServerStatusResponse::has_pending_buffer_size() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void ServerStatusResponse::set_has_pending_buffer_size() { + _has_bits_[0] |= 0x00000010u; +} +inline void ServerStatusResponse::clear_has_pending_buffer_size() { + _has_bits_[0] &= ~0x00000010u; +} +inline void ServerStatusResponse::clear_pending_buffer_size() { + pending_buffer_size_ = GOOGLE_LONGLONG(0); + clear_has_pending_buffer_size(); +} +inline ::google::protobuf::int64 ServerStatusResponse::pending_buffer_size() const { + return pending_buffer_size_; +} +inline void ServerStatusResponse::set_pending_buffer_size(::google::protobuf::int64 value) { + set_has_pending_buffer_size(); + pending_buffer_size_ = value; +} + +// optional int64 pending_data_size = 6; +inline bool ServerStatusResponse::has_pending_data_size() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void ServerStatusResponse::set_has_pending_data_size() { + _has_bits_[0] |= 0x00000020u; +} +inline void ServerStatusResponse::clear_has_pending_data_size() { + _has_bits_[0] &= ~0x00000020u; +} +inline void ServerStatusResponse::clear_pending_data_size() { + pending_data_size_ = GOOGLE_LONGLONG(0); + clear_has_pending_data_size(); +} +inline ::google::protobuf::int64 ServerStatusResponse::pending_data_size() const { + return pending_data_size_; +} +inline void ServerStatusResponse::set_pending_data_size(::google::protobuf::int64 value) { + set_has_pending_data_size(); + pending_data_size_ = value; +} + +// ------------------------------------------------------------------- + +// ListServiceRequest + +// ------------------------------------------------------------------- + +// ListServiceResponse + +// repeated string services = 1; +inline int ListServiceResponse::services_size() const { + return services_.size(); +} +inline void ListServiceResponse::clear_services() { + services_.Clear(); +} +inline const ::std::string& ListServiceResponse::services(int index) const { + return services_.Get(index); +} +inline ::std::string* ListServiceResponse::mutable_services(int index) { + return services_.Mutable(index); +} +inline void ListServiceResponse::set_services(int index, const ::std::string& value) { + services_.Mutable(index)->assign(value); +} +inline void ListServiceResponse::set_services(int index, const char* value) { + services_.Mutable(index)->assign(value); +} +inline void ListServiceResponse::set_services(int index, const char* value, size_t size) { + services_.Mutable(index)->assign( + reinterpret_cast(value), size); +} +inline ::std::string* ListServiceResponse::add_services() { + return services_.Add(); +} +inline void ListServiceResponse::add_services(const ::std::string& value) { + services_.Add()->assign(value); +} +inline void ListServiceResponse::add_services(const char* value) { + services_.Add()->assign(value); +} +inline void ListServiceResponse::add_services(const char* value, size_t size) { + services_.Add()->assign(reinterpret_cast(value), size); +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +ListServiceResponse::services() const { + return services_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +ListServiceResponse::mutable_services() { + return &services_; +} + +// repeated .google.protobuf.FileDescriptorProto files = 2; +inline int ListServiceResponse::files_size() const { + return files_.size(); +} +inline void ListServiceResponse::clear_files() { + files_.Clear(); +} +inline const ::google::protobuf::FileDescriptorProto& ListServiceResponse::files(int index) const { + return files_.Get(index); +} +inline ::google::protobuf::FileDescriptorProto* ListServiceResponse::mutable_files(int index) { + return files_.Mutable(index); +} +inline ::google::protobuf::FileDescriptorProto* ListServiceResponse::add_files() { + return files_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& +ListServiceResponse::files() const { + return files_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* +ListServiceResponse::mutable_files() { + return &files_; +} + +// ------------------------------------------------------------------- + +// MethodStat + +// optional string method_name = 1; +inline bool MethodStat::has_method_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void MethodStat::set_has_method_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void MethodStat::clear_has_method_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void MethodStat::clear_method_name() { + if (method_name_ != &::google::protobuf::internal::kEmptyString) { + method_name_->clear(); + } + clear_has_method_name(); +} +inline const ::std::string& MethodStat::method_name() const { + return *method_name_; +} +inline void MethodStat::set_method_name(const ::std::string& value) { + set_has_method_name(); + if (method_name_ == &::google::protobuf::internal::kEmptyString) { + method_name_ = new ::std::string; + } + method_name_->assign(value); +} +inline void MethodStat::set_method_name(const char* value) { + set_has_method_name(); + if (method_name_ == &::google::protobuf::internal::kEmptyString) { + method_name_ = new ::std::string; + } + method_name_->assign(value); +} +inline void MethodStat::set_method_name(const char* value, size_t size) { + set_has_method_name(); + if (method_name_ == &::google::protobuf::internal::kEmptyString) { + method_name_ = new ::std::string; + } + method_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* MethodStat::mutable_method_name() { + set_has_method_name(); + if (method_name_ == &::google::protobuf::internal::kEmptyString) { + method_name_ = new ::std::string; + } + return method_name_; +} +inline ::std::string* MethodStat::release_method_name() { + clear_has_method_name(); + if (method_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = method_name_; + method_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// optional int64 succeed_count = 2; +inline bool MethodStat::has_succeed_count() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void MethodStat::set_has_succeed_count() { + _has_bits_[0] |= 0x00000002u; +} +inline void MethodStat::clear_has_succeed_count() { + _has_bits_[0] &= ~0x00000002u; +} +inline void MethodStat::clear_succeed_count() { + succeed_count_ = GOOGLE_LONGLONG(0); + clear_has_succeed_count(); +} +inline ::google::protobuf::int64 MethodStat::succeed_count() const { + return succeed_count_; +} +inline void MethodStat::set_succeed_count(::google::protobuf::int64 value) { + set_has_succeed_count(); + succeed_count_ = value; +} + +// optional float succeed_avg_time_us = 3; +inline bool MethodStat::has_succeed_avg_time_us() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void MethodStat::set_has_succeed_avg_time_us() { + _has_bits_[0] |= 0x00000004u; +} +inline void MethodStat::clear_has_succeed_avg_time_us() { + _has_bits_[0] &= ~0x00000004u; +} +inline void MethodStat::clear_succeed_avg_time_us() { + succeed_avg_time_us_ = 0; + clear_has_succeed_avg_time_us(); +} +inline float MethodStat::succeed_avg_time_us() const { + return succeed_avg_time_us_; +} +inline void MethodStat::set_succeed_avg_time_us(float value) { + set_has_succeed_avg_time_us(); + succeed_avg_time_us_ = value; +} + +// optional int64 succeed_max_time_us = 4; +inline bool MethodStat::has_succeed_max_time_us() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void MethodStat::set_has_succeed_max_time_us() { + _has_bits_[0] |= 0x00000008u; +} +inline void MethodStat::clear_has_succeed_max_time_us() { + _has_bits_[0] &= ~0x00000008u; +} +inline void MethodStat::clear_succeed_max_time_us() { + succeed_max_time_us_ = GOOGLE_LONGLONG(0); + clear_has_succeed_max_time_us(); +} +inline ::google::protobuf::int64 MethodStat::succeed_max_time_us() const { + return succeed_max_time_us_; +} +inline void MethodStat::set_succeed_max_time_us(::google::protobuf::int64 value) { + set_has_succeed_max_time_us(); + succeed_max_time_us_ = value; +} + +// optional int64 failed_count = 5; +inline bool MethodStat::has_failed_count() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void MethodStat::set_has_failed_count() { + _has_bits_[0] |= 0x00000010u; +} +inline void MethodStat::clear_has_failed_count() { + _has_bits_[0] &= ~0x00000010u; +} +inline void MethodStat::clear_failed_count() { + failed_count_ = GOOGLE_LONGLONG(0); + clear_has_failed_count(); +} +inline ::google::protobuf::int64 MethodStat::failed_count() const { + return failed_count_; +} +inline void MethodStat::set_failed_count(::google::protobuf::int64 value) { + set_has_failed_count(); + failed_count_ = value; +} + +// optional float failed_avg_time_us = 6; +inline bool MethodStat::has_failed_avg_time_us() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void MethodStat::set_has_failed_avg_time_us() { + _has_bits_[0] |= 0x00000020u; +} +inline void MethodStat::clear_has_failed_avg_time_us() { + _has_bits_[0] &= ~0x00000020u; +} +inline void MethodStat::clear_failed_avg_time_us() { + failed_avg_time_us_ = 0; + clear_has_failed_avg_time_us(); +} +inline float MethodStat::failed_avg_time_us() const { + return failed_avg_time_us_; +} +inline void MethodStat::set_failed_avg_time_us(float value) { + set_has_failed_avg_time_us(); + failed_avg_time_us_ = value; +} + +// optional int64 failed_max_time_us = 7; +inline bool MethodStat::has_failed_max_time_us() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void MethodStat::set_has_failed_max_time_us() { + _has_bits_[0] |= 0x00000040u; +} +inline void MethodStat::clear_has_failed_max_time_us() { + _has_bits_[0] &= ~0x00000040u; +} +inline void MethodStat::clear_failed_max_time_us() { + failed_max_time_us_ = GOOGLE_LONGLONG(0); + clear_has_failed_max_time_us(); +} +inline ::google::protobuf::int64 MethodStat::failed_max_time_us() const { + return failed_max_time_us_; +} +inline void MethodStat::set_failed_max_time_us(::google::protobuf::int64 value) { + set_has_failed_max_time_us(); + failed_max_time_us_ = value; +} + +// ------------------------------------------------------------------- + +// ServiceStat + +// optional string service_name = 1; +inline bool ServiceStat::has_service_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ServiceStat::set_has_service_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void ServiceStat::clear_has_service_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ServiceStat::clear_service_name() { + if (service_name_ != &::google::protobuf::internal::kEmptyString) { + service_name_->clear(); + } + clear_has_service_name(); +} +inline const ::std::string& ServiceStat::service_name() const { + return *service_name_; +} +inline void ServiceStat::set_service_name(const ::std::string& value) { + set_has_service_name(); + if (service_name_ == &::google::protobuf::internal::kEmptyString) { + service_name_ = new ::std::string; + } + service_name_->assign(value); +} +inline void ServiceStat::set_service_name(const char* value) { + set_has_service_name(); + if (service_name_ == &::google::protobuf::internal::kEmptyString) { + service_name_ = new ::std::string; + } + service_name_->assign(value); +} +inline void ServiceStat::set_service_name(const char* value, size_t size) { + set_has_service_name(); + if (service_name_ == &::google::protobuf::internal::kEmptyString) { + service_name_ = new ::std::string; + } + service_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* ServiceStat::mutable_service_name() { + set_has_service_name(); + if (service_name_ == &::google::protobuf::internal::kEmptyString) { + service_name_ = new ::std::string; + } + return service_name_; +} +inline ::std::string* ServiceStat::release_service_name() { + clear_has_service_name(); + if (service_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = service_name_; + service_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// optional int64 period_seconds = 2; +inline bool ServiceStat::has_period_seconds() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void ServiceStat::set_has_period_seconds() { + _has_bits_[0] |= 0x00000002u; +} +inline void ServiceStat::clear_has_period_seconds() { + _has_bits_[0] &= ~0x00000002u; +} +inline void ServiceStat::clear_period_seconds() { + period_seconds_ = GOOGLE_LONGLONG(0); + clear_has_period_seconds(); +} +inline ::google::protobuf::int64 ServiceStat::period_seconds() const { + return period_seconds_; +} +inline void ServiceStat::set_period_seconds(::google::protobuf::int64 value) { + set_has_period_seconds(); + period_seconds_ = value; +} + +// optional int64 succeed_count = 3; +inline bool ServiceStat::has_succeed_count() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void ServiceStat::set_has_succeed_count() { + _has_bits_[0] |= 0x00000004u; +} +inline void ServiceStat::clear_has_succeed_count() { + _has_bits_[0] &= ~0x00000004u; +} +inline void ServiceStat::clear_succeed_count() { + succeed_count_ = GOOGLE_LONGLONG(0); + clear_has_succeed_count(); +} +inline ::google::protobuf::int64 ServiceStat::succeed_count() const { + return succeed_count_; +} +inline void ServiceStat::set_succeed_count(::google::protobuf::int64 value) { + set_has_succeed_count(); + succeed_count_ = value; +} + +// optional int64 failed_count = 4; +inline bool ServiceStat::has_failed_count() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void ServiceStat::set_has_failed_count() { + _has_bits_[0] |= 0x00000008u; +} +inline void ServiceStat::clear_has_failed_count() { + _has_bits_[0] &= ~0x00000008u; +} +inline void ServiceStat::clear_failed_count() { + failed_count_ = GOOGLE_LONGLONG(0); + clear_has_failed_count(); +} +inline ::google::protobuf::int64 ServiceStat::failed_count() const { + return failed_count_; +} +inline void ServiceStat::set_failed_count(::google::protobuf::int64 value) { + set_has_failed_count(); + failed_count_ = value; +} + +// repeated .sofa.pbrpc.builtin.MethodStat method_stats = 5; +inline int ServiceStat::method_stats_size() const { + return method_stats_.size(); +} +inline void ServiceStat::clear_method_stats() { + method_stats_.Clear(); +} +inline const ::sofa::pbrpc::builtin::MethodStat& ServiceStat::method_stats(int index) const { + return method_stats_.Get(index); +} +inline ::sofa::pbrpc::builtin::MethodStat* ServiceStat::mutable_method_stats(int index) { + return method_stats_.Mutable(index); +} +inline ::sofa::pbrpc::builtin::MethodStat* ServiceStat::add_method_stats() { + return method_stats_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::sofa::pbrpc::builtin::MethodStat >& +ServiceStat::method_stats() const { + return method_stats_; +} +inline ::google::protobuf::RepeatedPtrField< ::sofa::pbrpc::builtin::MethodStat >* +ServiceStat::mutable_method_stats() { + return &method_stats_; +} + +// ------------------------------------------------------------------- + +// StatRequest + +// optional string service_name = 1 [default = "all"]; +inline bool StatRequest::has_service_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void StatRequest::set_has_service_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void StatRequest::clear_has_service_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void StatRequest::clear_service_name() { + if (service_name_ != &_default_service_name_) { + service_name_->assign(_default_service_name_); + } + clear_has_service_name(); +} +inline const ::std::string& StatRequest::service_name() const { + return *service_name_; +} +inline void StatRequest::set_service_name(const ::std::string& value) { + set_has_service_name(); + if (service_name_ == &_default_service_name_) { + service_name_ = new ::std::string; + } + service_name_->assign(value); +} +inline void StatRequest::set_service_name(const char* value) { + set_has_service_name(); + if (service_name_ == &_default_service_name_) { + service_name_ = new ::std::string; + } + service_name_->assign(value); +} +inline void StatRequest::set_service_name(const char* value, size_t size) { + set_has_service_name(); + if (service_name_ == &_default_service_name_) { + service_name_ = new ::std::string; + } + service_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* StatRequest::mutable_service_name() { + set_has_service_name(); + if (service_name_ == &_default_service_name_) { + service_name_ = new ::std::string(_default_service_name_); + } + return service_name_; +} +inline ::std::string* StatRequest::release_service_name() { + clear_has_service_name(); + if (service_name_ == &_default_service_name_) { + return NULL; + } else { + ::std::string* temp = service_name_; + service_name_ = const_cast< ::std::string*>(&_default_service_name_); + return temp; + } +} + +// optional int64 period_seconds = 2 [default = 60]; +inline bool StatRequest::has_period_seconds() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void StatRequest::set_has_period_seconds() { + _has_bits_[0] |= 0x00000002u; +} +inline void StatRequest::clear_has_period_seconds() { + _has_bits_[0] &= ~0x00000002u; +} +inline void StatRequest::clear_period_seconds() { + period_seconds_ = GOOGLE_LONGLONG(60); + clear_has_period_seconds(); +} +inline ::google::protobuf::int64 StatRequest::period_seconds() const { + return period_seconds_; +} +inline void StatRequest::set_period_seconds(::google::protobuf::int64 value) { + set_has_period_seconds(); + period_seconds_ = value; +} + +// ------------------------------------------------------------------- + +// StatResponse + +// repeated .sofa.pbrpc.builtin.ServiceStat service_stats = 1; +inline int StatResponse::service_stats_size() const { + return service_stats_.size(); +} +inline void StatResponse::clear_service_stats() { + service_stats_.Clear(); +} +inline const ::sofa::pbrpc::builtin::ServiceStat& StatResponse::service_stats(int index) const { + return service_stats_.Get(index); +} +inline ::sofa::pbrpc::builtin::ServiceStat* StatResponse::mutable_service_stats(int index) { + return service_stats_.Mutable(index); +} +inline ::sofa::pbrpc::builtin::ServiceStat* StatResponse::add_service_stats() { + return service_stats_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::sofa::pbrpc::builtin::ServiceStat >& +StatResponse::service_stats() const { + return service_stats_; +} +inline ::google::protobuf::RepeatedPtrField< ::sofa::pbrpc::builtin::ServiceStat >* +StatResponse::mutable_service_stats() { + return &service_stats_; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace builtin +} // namespace pbrpc +} // namespace sofa + +#ifndef SWIG +namespace google { +namespace protobuf { + + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_sofa_2fpbrpc_2fbuiltin_5fservice_2eproto__INCLUDED diff --git a/src/sofa/pbrpc/builtin_service.proto b/src/sofa/pbrpc/builtin_service.proto new file mode 100644 index 0000000..34b196e --- /dev/null +++ b/src/sofa/pbrpc/builtin_service.proto @@ -0,0 +1,129 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +import "google/protobuf/descriptor.proto"; +import "sofa/pbrpc/rpc_option.proto"; + +package sofa.pbrpc.builtin; + +option cc_generic_services = true; + +message HealthRequest { +} + +message HealthResponse { + optional string health = 1; +} + +message ServerOptions { + optional int64 work_thread_num = 1; + optional int64 keep_alive_time = 2; + optional int64 max_pending_buffer_size = 3; + optional int64 max_throughput_in = 4; + optional int64 max_throughput_out = 5; + optional bool disable_builtin_services = 6; + optional bool disable_list_service = 7; +} + +message ServerOptionsRequest { +} + +message ServerOptionsResponse { + optional ServerOptions options = 1; +} + +// Update server options. Only the following options can be update: +// - keep_alive_time +// - max_pending_buffer_size +// - max_throughput_in +// - max_throughput_out +// If not set, then use old value. +message UpdateOptionsRequest { + optional ServerOptions options = 1; +} + +// If succeed, returns new values. +message UpdateOptionsResponse { + optional ServerOptions options = 1; +} + +message ServerStatusRequest { +} + +message ServerStatusResponse { + optional bool is_listening = 1; + + // count of client connections. + optional int64 connection_count = 2; + + // count of registered services. + optional int64 service_count = 3; + + // total count of pending messages. + optional int64 pending_message_count = 4; + + // total size of pending buffers occupied by pending messages. + optional int64 pending_buffer_size = 5; + + // total size of pending data in pending messages, may by less than pending_buffer_size. + optional int64 pending_data_size = 6; +} + +message ListServiceRequest { +} + +message ListServiceResponse { + // full name of all registered services. + repeated string services = 1; + + // descriptor of all dependency proto files. + repeated google.protobuf.FileDescriptorProto files = 2; +} + +message MethodStat { + optional string method_name = 1; + optional int64 succeed_count = 2; + optional float succeed_avg_time_us = 3; + optional int64 succeed_max_time_us = 4; + optional int64 failed_count = 5; + optional float failed_avg_time_us = 6; + optional int64 failed_max_time_us = 7; +} + +message ServiceStat { + optional string service_name = 1; + optional int64 period_seconds = 2; + optional int64 succeed_count = 3; + optional int64 failed_count = 4; + repeated MethodStat method_stats = 5; +} + +message StatRequest { + optional string service_name = 1 [default = "all"]; + optional int64 period_seconds = 2 [default = 60]; // expect period in seconds +} + +message StatResponse { + repeated ServiceStat service_stats = 1; +} + +service BuiltinService { + option (sofa.pbrpc.service_timeout) = 3000; + + rpc Health(HealthRequest) returns (HealthResponse); + + rpc ServerOptions(ServerOptionsRequest) returns (ServerOptionsResponse); + + rpc UpdateOptions(UpdateOptionsRequest) returns (UpdateOptionsResponse); + + rpc ServerStatus(ServerStatusRequest) returns (ServerStatusResponse); + + rpc ListService(ListServiceRequest) returns (ListServiceResponse) { + option (sofa.pbrpc.response_compress_type) = CompressTypeGzip; + } + + rpc Stat(StatRequest) returns (StatResponse); +} diff --git a/src/sofa/pbrpc/builtin_service_impl.cc b/src/sofa/pbrpc/builtin_service_impl.cc new file mode 100644 index 0000000..af431a5 --- /dev/null +++ b/src/sofa/pbrpc/builtin_service_impl.cc @@ -0,0 +1,210 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include +#include +#include + +namespace sofa { +namespace pbrpc { +namespace builtin { + +// Copy from RpcServerOptions to protobuf ServerOptions. +static void CopyOptions(const RpcServerOptions& options, + ::sofa::pbrpc::builtin::ServerOptions* options_pb) +{ + options_pb->set_work_thread_num(options.work_thread_num); + options_pb->set_keep_alive_time(options.keep_alive_time); + options_pb->set_max_pending_buffer_size(options.max_pending_buffer_size); + options_pb->set_max_throughput_in(options.max_throughput_in); + options_pb->set_max_throughput_out(options.max_throughput_out); + options_pb->set_disable_builtin_services(options.disable_builtin_services); + options_pb->set_disable_list_service(options.disable_list_service); +} + +BuiltinServiceImpl::BuiltinServiceImpl( + const RpcServerImplWPtr& rpc_server, + const ServicePoolWPtr& service_pool, + bool disable_list_service) + : _rpc_server(rpc_server) + , _service_pool(service_pool) + , _disable_list_service(disable_list_service) + , _list_service_last_count(0) +{ +} + +BuiltinServiceImpl::~BuiltinServiceImpl() +{ +} + +void BuiltinServiceImpl::Health(::google::protobuf::RpcController* /* controller */, + const ::sofa::pbrpc::builtin::HealthRequest* /* request */, + ::sofa::pbrpc::builtin::HealthResponse* response, + ::google::protobuf::Closure* done) +{ + RpcServerImplPtr server = _rpc_server.lock(); + if (server && server->IsListening()) { + response->set_health("OK"); + } else { + response->set_health("NotOK"); + } + done->Run(); +} + +void BuiltinServiceImpl::ServerOptions(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::ServerOptionsRequest* /* request */, + ::sofa::pbrpc::builtin::ServerOptionsResponse* response, + ::google::protobuf::Closure* done) +{ + RpcServerImplPtr server = _rpc_server.lock(); + if (!server) { + controller->SetFailed("server not exist"); + done->Run(); + return; + } + CopyOptions(server->GetOptions(), response->mutable_options()); + done->Run(); +} + +void BuiltinServiceImpl::UpdateOptions(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::UpdateOptionsRequest* request, + ::sofa::pbrpc::builtin::UpdateOptionsResponse* response, + ::google::protobuf::Closure* done) +{ + if (!request->has_options()) { + controller->SetFailed("options not set"); + done->Run(); + return; + } + const ::sofa::pbrpc::builtin::ServerOptions& request_options = request->options(); + if (!request_options.has_keep_alive_time() + && !request_options.has_max_pending_buffer_size() + && !request_options.has_max_throughput_in() + && !request_options.has_max_throughput_out()) + { + controller->SetFailed("no option need to update"); + done->Run(); + return; + } + RpcServerImplPtr server = _rpc_server.lock(); + if (!server) { + controller->SetFailed("server not exist"); + done->Run(); + return; + } + RpcServerOptions options = server->GetOptions(); + if (request_options.has_keep_alive_time()) { + options.keep_alive_time = request_options.keep_alive_time(); + } + if (request_options.has_max_pending_buffer_size()) { + options.max_pending_buffer_size = request_options.max_pending_buffer_size(); + } + if (request_options.has_max_throughput_in()) { + options.max_throughput_in = request_options.max_throughput_in(); + } + if (request_options.has_max_throughput_out()) { + options.max_throughput_out = request_options.max_throughput_out(); + } +#if defined( LOG ) + LOG(INFO) << "UpdateOptions(): update by builtin service"; +#else + SLOG(INFO, "UpdateOptions(): update by builtin service"); +#endif + server->ResetOptions(options); + CopyOptions(server->GetOptions(), response->mutable_options()); + done->Run(); +} + +void BuiltinServiceImpl::ServerStatus(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::ServerStatusRequest* /* request */, + ::sofa::pbrpc::builtin::ServerStatusResponse* response, + ::google::protobuf::Closure* done) +{ + RpcServerImplPtr server = _rpc_server.lock(); + if (!server) { + controller->SetFailed("server not exist"); + done->Run(); + return; + } + int64 pending_message_count; + int64 pending_buffer_size; + int64 pending_data_size; + server->GetPendingStat(&pending_message_count, &pending_buffer_size, &pending_data_size); + response->set_is_listening(server->IsListening()); + response->set_connection_count(server->ConnectionCount()); + response->set_service_count(server->ServiceCount()); + response->set_pending_message_count(pending_message_count); + response->set_pending_buffer_size(pending_buffer_size); + response->set_pending_data_size(pending_data_size); + done->Run(); +} + +void BuiltinServiceImpl::ListService(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::ListServiceRequest* /* request */, + ::sofa::pbrpc::builtin::ListServiceResponse* response, + ::google::protobuf::Closure* done) +{ + if (_disable_list_service) { + controller->SetFailed("service disabled"); + done->Run(); + return; + } + ScopedLocker _(_list_service_lock); + ServicePoolPtr pool = _service_pool.lock(); + if (!pool) { + controller->SetFailed("service pool not exist"); + done->Run(); + return; + } + if (_list_service_last_count == pool->ServiceCount()) { + response->CopyFrom(_list_service_last_response); + done->Run(); + return; + } + _list_service_last_response.Clear(); + pool->ListService(&_list_service_last_response); + response->CopyFrom(_list_service_last_response); + done->Run(); +} + +void BuiltinServiceImpl::Stat(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::StatRequest* request, + ::sofa::pbrpc::builtin::StatResponse* response, + ::google::protobuf::Closure* done) +{ + ServicePoolPtr pool = _service_pool.lock(); + if (!pool) { + controller->SetFailed("service pool not exist"); + done->Run(); + return; + } + if (request->service_name() == "all") { + std::list svc_list; + pool->ListService(&svc_list); + for (std::list::iterator it = svc_list.begin(); + it != svc_list.end(); ++it) { + ServiceBoard* board = *it; + board->LatestStats(request->period_seconds(), response->add_service_stats()); + } + done->Run(); + } + else { + ServiceBoard* board = pool->FindService(request->service_name()); + if (board == NULL) { + controller->SetFailed("service not exist"); + done->Run(); + return; + } + board->LatestStats(request->period_seconds(), response->add_service_stats()); + done->Run(); + } +} + +} // namespace builtin +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/builtin_service_impl.h b/src/sofa/pbrpc/builtin_service_impl.h new file mode 100644 index 0000000..cb6ee2a --- /dev/null +++ b/src/sofa/pbrpc/builtin_service_impl.h @@ -0,0 +1,70 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_BUILTIN_SERVICE_IMPL_H_ +#define _SOFA_PBRPC_BUILTIN_SERVICE_IMPL_H_ + +#include +#include + +namespace sofa { +namespace pbrpc { +namespace builtin { + +class BuiltinServiceImpl : public BuiltinService { +public: + BuiltinServiceImpl(const RpcServerImplWPtr& rpc_server, + const ServicePoolWPtr& service_pool, + bool disable_list_service = false); + virtual ~BuiltinServiceImpl(); + + virtual void Health(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::HealthRequest* request, + ::sofa::pbrpc::builtin::HealthResponse* response, + ::google::protobuf::Closure* done); + + virtual void ServerOptions(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::ServerOptionsRequest* request, + ::sofa::pbrpc::builtin::ServerOptionsResponse* response, + ::google::protobuf::Closure* done); + + virtual void UpdateOptions(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::UpdateOptionsRequest* request, + ::sofa::pbrpc::builtin::UpdateOptionsResponse* response, + ::google::protobuf::Closure* done); + + virtual void ServerStatus(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::ServerStatusRequest* request, + ::sofa::pbrpc::builtin::ServerStatusResponse* response, + ::google::protobuf::Closure* done); + + virtual void ListService(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::ListServiceRequest* request, + ::sofa::pbrpc::builtin::ListServiceResponse* response, + ::google::protobuf::Closure* done); + + virtual void Stat(::google::protobuf::RpcController* controller, + const ::sofa::pbrpc::builtin::StatRequest* request, + ::sofa::pbrpc::builtin::StatResponse* response, + ::google::protobuf::Closure* done); + +private: + RpcServerImplWPtr _rpc_server; + ServicePoolWPtr _service_pool; + bool _disable_list_service; + + MutexLock _list_service_lock; + ListServiceResponse _list_service_last_response; + int _list_service_last_count; +}; + +} // namespace builtin +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_BUILTIN_SERVICE_IMPL_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/closure.h b/src/sofa/pbrpc/closure.h new file mode 100644 index 0000000..cae37b0 --- /dev/null +++ b/src/sofa/pbrpc/closure.h @@ -0,0 +1,1001 @@ +#ifndef _SOFA_PBRPC_CLOSURE_H_ +#define _SOFA_PBRPC_CLOSURE_H_ + +///////////////////////////////////////////////////// +// DO NOT EDIT!!! +// this header file is auto generated by perl script +// edit the generator if necessary +///////////////////////////////////////////////////// + +///////////////////////////////////////////////////// +// This `Closure' only support pre-bind arguments. +// Use `ExtClosure' if you need post-bind arguments. +///////////////////////////////////////////////////// + +///////////////////////////////////////////////////// +// Support: +// 1, Compatible with google::protobuf::Closure. +// 2, Support pre-bind for general function and class +// method, up to 10 arguments. +// 3, Support pass argument by reference, though bind +// always by value. +// 4, When bind class method, support use +// "sofa::pbrpc::shared_ptr" as this pointer of class. +// 5, Support create temporary and permanent closure: +// Temporary closure (self destoryed after call): +// NewClosure(); +// Permanent closure (do not destoryed by self): +// NewPermanentClosure(); +///////////////////////////////////////////////////// + +///////////////////////////////////////////////////// +// Usage: +// 1, General function: +// +// void f1(int pre_arg, double post_arg); +// Closure* c1 = NewClosure(&f1, 1, 2.0); +// c1->Run(2.0); +// +// 2, Class method: +// +// class ClassA +// { +// public: +// int m1(int pre_arg, double post_arg); +// }; +// ClassA obj; +// Closure* c3 = NewClosure(&obj, &ClassA::m1, 1, 2.0); +// c3->Run(); +// +// class ClassB : public sofa::pbrpc::enable_shared_from_this +// { +// public: +// int m1(int pre_arg, double post_arg); +// +// void m2() +// { +// Closure* c4 = NewClosure(shared_from_this(), &ClassB::m1, 1, 2.0); +// c4->Run(2.0); +// } +// }; +// sofa::pbrpc::shared_ptr ptr(new ClassB); +// Closure* c5 = NewClosure(ptr, &ClassB::m1, 1, 2.0); +// c5->Run(); +// +///////////////////////////////////////////////////// + +#include +#include + +namespace sofa { +namespace pbrpc{ + +/// base class for all Closures +class ClosureBase : public google::protobuf::Closure +{ +public: + virtual ~ClosureBase() {} + virtual bool IsSelfDelete() const = 0; +}; +//////////////////////////////////////////////////// +//////////// class method closures ///////////////// +//////////////////////////////////////////////////// + +template +class MethodClosure_Bind0 : public ClosureBase { +public: + typedef void (MethodClass::*MethodType)(); + MethodClosure_Bind0(ClassPointer object, MethodType method): + m_object(object), m_method(method) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; +}; + +template +class MethodClosure_Bind1 : public ClosureBase { +public: + typedef void (MethodClass::*MethodType)(PreArg1); + MethodClosure_Bind1(ClassPointer object, MethodType method, PreArg1 pa1): + m_object(object), m_method(method), m_pa1(pa1) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; +}; + +template +class MethodClosure_Bind2 : public ClosureBase { +public: + typedef void (MethodClass::*MethodType)(PreArg1, PreArg2); + MethodClosure_Bind2(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template +class MethodClosure_Bind3 : public ClosureBase { +public: + typedef void (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3); + MethodClosure_Bind3(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template +class MethodClosure_Bind4 : public ClosureBase { +public: + typedef void (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4); + MethodClosure_Bind4(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template +class MethodClosure_Bind5 : public ClosureBase { +public: + typedef void (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5); + MethodClosure_Bind5(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template +class MethodClosure_Bind6 : public ClosureBase { +public: + typedef void (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6); + MethodClosure_Bind6(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template +class MethodClosure_Bind7 : public ClosureBase { +public: + typedef void (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7); + MethodClosure_Bind7(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template +class MethodClosure_Bind8 : public ClosureBase { +public: + typedef void (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8); + MethodClosure_Bind8(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template +class MethodClosure_Bind9 : public ClosureBase { +public: + typedef void (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9); + MethodClosure_Bind9(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template +class MethodClosure_Bind10 : public ClosureBase { +public: + typedef void (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10); + MethodClosure_Bind10(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +//////////////////////////////////////////////////// +//////////// nomal function closures ///////////////n//////////////////////////////////////////////////// + +template +class FunctionClosure_Bind0 : public ClosureBase { +public: + typedef void (*FunctionType)(); + FunctionClosure_Bind0(FunctionType function): + m_function(function) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; +}; + +template +class FunctionClosure_Bind1 : public ClosureBase { +public: + typedef void (*FunctionType)(PreArg1); + FunctionClosure_Bind1(FunctionType function, PreArg1 pa1): + m_function(function), m_pa1(pa1) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; +}; + +template +class FunctionClosure_Bind2 : public ClosureBase { +public: + typedef void (*FunctionType)(PreArg1, PreArg2); + FunctionClosure_Bind2(FunctionType function, PreArg1 pa1, PreArg2 pa2): + m_function(function), m_pa1(pa1), m_pa2(pa2) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template +class FunctionClosure_Bind3 : public ClosureBase { +public: + typedef void (*FunctionType)(PreArg1, PreArg2, PreArg3); + FunctionClosure_Bind3(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template +class FunctionClosure_Bind4 : public ClosureBase { +public: + typedef void (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4); + FunctionClosure_Bind4(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template +class FunctionClosure_Bind5 : public ClosureBase { +public: + typedef void (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5); + FunctionClosure_Bind5(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template +class FunctionClosure_Bind6 : public ClosureBase { +public: + typedef void (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6); + FunctionClosure_Bind6(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template +class FunctionClosure_Bind7 : public ClosureBase { +public: + typedef void (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7); + FunctionClosure_Bind7(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template +class FunctionClosure_Bind8 : public ClosureBase { +public: + typedef void (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8); + FunctionClosure_Bind8(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template +class FunctionClosure_Bind9 : public ClosureBase { +public: + typedef void (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9); + FunctionClosure_Bind9(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template +class FunctionClosure_Bind10 : public ClosureBase { +public: + typedef void (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10); + FunctionClosure_Bind10(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual void Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +//////////////////////////////////////////////////// +//////// Closure create helper functions /////////// +//////////////////////////////////////////////////// +//////////// for class method ////////////////////// + +template +ClosureBase* NewClosure(ClassPointer object, void(MethodClass::*method)()) { + return new MethodClosure_Bind0(object, method); +} + +template +ClosureBase* NewClosure(ClassPointer object, void(MethodClass::*method)(PreArg1) + , typename ParamTraits::ForwardType pa1) { + return new MethodClosure_Bind1(object, method, pa1); +} + +template +ClosureBase* NewClosure(ClassPointer object, void(MethodClass::*method)(PreArg1, PreArg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodClosure_Bind2(object, method, pa1, pa2); +} + +template +ClosureBase* NewClosure(ClassPointer object, void(MethodClass::*method)(PreArg1, PreArg2, PreArg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodClosure_Bind3(object, method, pa1, pa2, pa3); +} + +template +ClosureBase* NewClosure(ClassPointer object, void(MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodClosure_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ClosureBase* NewClosure(ClassPointer object, void(MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodClosure_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ClosureBase* NewClosure(ClassPointer object, void(MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodClosure_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ClosureBase* NewClosure(ClassPointer object, void(MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodClosure_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ClosureBase* NewClosure(ClassPointer object, void(MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodClosure_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ClosureBase* NewClosure(ClassPointer object, void(MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodClosure_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ClosureBase* NewClosure(ClassPointer object, void(MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodClosure_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +//////////////////////////////////////////////////// +//////// Closure create helper functions /////////// +//////////////////////////////////////////////////// +//////////// for class method ////////////////////// + +template +ClosureBase* NewPermanentClosure(ClassPointer object, void(MethodClass::*method)()) { + return new MethodClosure_Bind0(object, method); +} + +template +ClosureBase* NewPermanentClosure(ClassPointer object, void(MethodClass::*method)(PreArg1) + , typename ParamTraits::ForwardType pa1) { + return new MethodClosure_Bind1(object, method, pa1); +} + +template +ClosureBase* NewPermanentClosure(ClassPointer object, void(MethodClass::*method)(PreArg1, PreArg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodClosure_Bind2(object, method, pa1, pa2); +} + +template +ClosureBase* NewPermanentClosure(ClassPointer object, void(MethodClass::*method)(PreArg1, PreArg2, PreArg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodClosure_Bind3(object, method, pa1, pa2, pa3); +} + +template +ClosureBase* NewPermanentClosure(ClassPointer object, void(MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodClosure_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ClosureBase* NewPermanentClosure(ClassPointer object, void(MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodClosure_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ClosureBase* NewPermanentClosure(ClassPointer object, void(MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodClosure_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ClosureBase* NewPermanentClosure(ClassPointer object, void(MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodClosure_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ClosureBase* NewPermanentClosure(ClassPointer object, void(MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodClosure_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ClosureBase* NewPermanentClosure(ClassPointer object, void(MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodClosure_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ClosureBase* NewPermanentClosure(ClassPointer object, void(MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodClosure_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +//////////////////////////////////////////////////// +//////// Closure create helper functions /////////// +//////////////////////////////////////////////////// +//////////// for nomal function //////////////////// + +inline +ClosureBase* NewClosure(void(*function)()) { + return new FunctionClosure_Bind0(function); +} + +template +ClosureBase* NewClosure(void(*function)(PreArg1) + , typename ParamTraits::ForwardType pa1) { + return new FunctionClosure_Bind1(function, pa1); +} + +template +ClosureBase* NewClosure(void(*function)(PreArg1, PreArg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionClosure_Bind2(function, pa1, pa2); +} + +template +ClosureBase* NewClosure(void(*function)(PreArg1, PreArg2, PreArg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionClosure_Bind3(function, pa1, pa2, pa3); +} + +template +ClosureBase* NewClosure(void(*function)(PreArg1, PreArg2, PreArg3, PreArg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionClosure_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ClosureBase* NewClosure(void(*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionClosure_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ClosureBase* NewClosure(void(*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionClosure_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ClosureBase* NewClosure(void(*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionClosure_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ClosureBase* NewClosure(void(*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionClosure_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ClosureBase* NewClosure(void(*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionClosure_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ClosureBase* NewClosure(void(*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionClosure_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +//////////////////////////////////////////////////// +//////// Closure create helper functions /////////// +//////////////////////////////////////////////////// +//////////// for nomal function //////////////////// + +inline +ClosureBase* NewPermanentClosure(void(*function)()) { + return new FunctionClosure_Bind0(function); +} + +template +ClosureBase* NewPermanentClosure(void(*function)(PreArg1) + , typename ParamTraits::ForwardType pa1) { + return new FunctionClosure_Bind1(function, pa1); +} + +template +ClosureBase* NewPermanentClosure(void(*function)(PreArg1, PreArg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionClosure_Bind2(function, pa1, pa2); +} + +template +ClosureBase* NewPermanentClosure(void(*function)(PreArg1, PreArg2, PreArg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionClosure_Bind3(function, pa1, pa2, pa3); +} + +template +ClosureBase* NewPermanentClosure(void(*function)(PreArg1, PreArg2, PreArg3, PreArg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionClosure_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ClosureBase* NewPermanentClosure(void(*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionClosure_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ClosureBase* NewPermanentClosure(void(*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionClosure_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ClosureBase* NewPermanentClosure(void(*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionClosure_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ClosureBase* NewPermanentClosure(void(*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionClosure_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ClosureBase* NewPermanentClosure(void(*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionClosure_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ClosureBase* NewPermanentClosure(void(*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionClosure_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_CLOSURE_H_ diff --git a/src/sofa/pbrpc/closure_gen.pl b/src/sofa/pbrpc/closure_gen.pl new file mode 100644 index 0000000..8464247 --- /dev/null +++ b/src/sofa/pbrpc/closure_gen.pl @@ -0,0 +1,326 @@ +#!/usr/bin/perl -w + +use strict; +use warnings; + +#this perl script is used to generate Closure + +my $kPreMaxArgs = 10; + +sub PrintHead() +{ + print "#ifndef _SOFA_PBRPC_CLOSURE_H_\n"; + print "#define _SOFA_PBRPC_CLOSURE_H_\n\n"; + + print "/////////////////////////////////////////////////////\n"; + print "// DO NOT EDIT!!!\n"; + print "// this header file is auto generated by perl script\n"; + print "// edit the generator if necessary\n"; + print "/////////////////////////////////////////////////////\n\n"; + + print "/////////////////////////////////////////////////////\n"; + print "// This `Closure' only support pre-bind arguments.\n"; + print "// Use `ExtClosure' if you need post-bind arguments.\n"; + print "/////////////////////////////////////////////////////\n\n"; + + print "/////////////////////////////////////////////////////\n"; + print "// Support:\n"; + print "// 1, Compatible with google::protobuf::Closure.\n"; + print "// 2, Support pre-bind for general function and class\n"; + print "// method, up to 10 arguments.\n"; + print "// 3, Support pass argument by reference, though bind\n"; + print "// always by value.\n"; + print "// 4, When bind class method, support use\n"; + print "// \"sofa::pbrpc::shared_ptr\" as this pointer of class.\n"; + print "// 5, Support create temporary and permanent closure:\n"; + print "// Temporary closure (self destoryed after call):\n"; + print "// NewClosure();\n"; + print "// Permanent closure (do not destoryed by self):\n"; + print "// NewPermanentClosure();\n"; + print "/////////////////////////////////////////////////////\n\n"; + + print "/////////////////////////////////////////////////////\n"; + print "// Usage:\n"; + print "// 1, General function:\n"; + print "// \n"; + print "// void f1(int pre_arg, double post_arg);\n"; + print "// Closure* c1 = NewClosure(&f1, 1, 2.0);\n"; + print "// c1->Run(2.0);\n"; + print "// \n"; + print "// 2, Class method:\n"; + print "// \n"; + print "// class ClassA\n"; + print "// {\n"; + print "// public:\n"; + print "// int m1(int pre_arg, double post_arg);\n"; + print "// };\n"; + print "// ClassA obj;\n"; + print "// Closure* c3 = NewClosure(&obj, &ClassA::m1, 1, 2.0);\n"; + print "// c3->Run();\n"; + print "// \n"; + print "// class ClassB : public sofa::pbrpc::enable_shared_from_this\n"; + print "// {\n"; + print "// public:\n"; + print "// int m1(int pre_arg, double post_arg);\n"; + print "// \n"; + print "// void m2()\n"; + print "// {\n"; + print "// Closure* c4 = NewClosure(shared_from_this(), &ClassB::m1, 1, 2.0);\n"; + print "// c4->Run(2.0);\n"; + print "// }\n"; + print "// };\n"; + print "// sofa::pbrpc::shared_ptr ptr(new ClassB);\n"; + print "// Closure* c5 = NewClosure(ptr, &ClassB::m1, 1, 2.0);\n"; + print "// c5->Run();\n"; + print "// \n"; + print "/////////////////////////////////////////////////////\n\n"; + + print "#include \n"; + print "#include \n\n"; + + print "namespace sofa {\n"; + print "namespace pbrpc{\n"; +} + +sub PrintEnd +{ + print "} // namespace pbrpc\n"; + print "} // namespace sofa\n\n"; + + print "#endif // _SOFA_PBRPC_CLOSURE_H_\n"; +} + +sub PrintClosureBase() +{ + print " +/// base class for all Closures +class ClosureBase : public google::protobuf::Closure +{ +public: + virtual ~ClosureBase() {} + virtual bool IsSelfDelete() const = 0; +}; +" +} + +sub PrintClosure_Bind($$) +{ + my ($type, $num_pre_args) = @_; + my $k; + + # print template argument list + print "template \n"; + + # print class definition + my $ClassName = "${type}Closure_Bind${num_pre_args}"; + print "class ${ClassName} : public ClosureBase {\n"; + print "public:\n"; + + # print typedef + print " typedef void ("; + print "MethodClass::" if ($type eq "Method"); + print "*${type}Type)("; + for ($k = 1; $k <= $num_pre_args; $k++) + { + print "PreArg$k"; + print ", " if ($k < $num_pre_args); + } + print ");\n"; + + # print ctor + print " $ClassName("; + if ($type eq "Method") + { + print "ClassPointer object, MethodType method"; + } + elsif ($type eq "Function") + { + print "FunctionType function"; + } + for ($k = 1; $k <= $num_pre_args; $k++) + { + print ", PreArg$k pa$k"; + } + print "):\n "; + if ($type eq "Method") + { + print "m_object(object), m_method(method)"; + } + elsif ($type eq "Function") + { + print "m_function(function)"; + } + for ($k = 1; $k <= $num_pre_args; $k++) + { + print ", m_pa${k}(pa${k})"; + } + print " {}\n"; + + # print the `Run' function + print " virtual void Run() {\n"; + print " ConditionalAutoDeleter self_deleter(this);\n"; + print " return "; + if ($type eq "Method") + { + print "(get_pointer(m_object)->*m_method)("; + } + elsif ($type eq "Function") + { + print "m_function("; + } + for ($k = 1; $k <= $num_pre_args; $k++) + { + print "m_pa$k"; + print ", " if $k != $num_pre_args; + } + print ");\n"; + print " }\n"; + + # IsSelfDelete + print " virtual bool IsSelfDelete() const { return SelfDeleting; }\n"; + + # member variables + print "private:\n"; + if ($type eq "Method") + { + print " ClassPointer m_object;\n MethodType m_method;\n"; + } + if ($type eq "Function") + { + print " FunctionType m_function;\n"; + } + for ($k = 1; $k <= $num_pre_args; $k++) + { + print " typename ParamTraits::StorageType m_pa${k};\n"; + } + print "};\n\n"; +} + +sub PrintAllClosure_Binds($) +{ + my ($type) = @_; + print "////////////////////////////////////////////////////\n"; + + if ($type eq "Method") + { + print "//////////// class method closures /////////////////\n"; + } + else + { + print "//////////// nomal function closures ///////////////n"; + } + print "////////////////////////////////////////////////////\n\n"; + + for (my $num_pre_args = 0; $num_pre_args <= $kPreMaxArgs; $num_pre_args++) + { + PrintClosure_Bind($type, $num_pre_args); + } +} + +sub PrintNewClosure($$) +{ + my ($type, $self_deleting) = @_; + print "////////////////////////////////////////////////////\n"; + print "//////// Closure create helper functions ///////////\n"; + print "////////////////////////////////////////////////////\n"; + if ($type eq "Method") + { + print "//////////// for class method //////////////////////\n\n"; + } + else + { + print "//////////// for nomal function ////////////////////\n\n"; + } + + for (my $num_pre_args = 0; $num_pre_args <= $kPreMaxArgs; $num_pre_args++) + { + my $k; + if ($type eq "Method" || $num_pre_args > 0) + { + print "template <"; + print "typename ClassPointer, typename MethodClass" if ($type eq "Method"); + for ($k = 1; $k <= $num_pre_args; $k++) + { + print ", " if ($type eq "Method" || $k > 1); + print "typename PreArg$k"; + } + print ">\n"; + } + else + { + print "inline\n"; + } + if ($self_deleting eq "false") + { + print "ClosureBase* NewPermanentClosure("; + } + else + { + print "ClosureBase* NewClosure("; + } + if ($type eq "Method") + { + print "ClassPointer object, void(MethodClass::*method)("; + } + else + { + print "void(*function)("; + } + for ($k = 1; $k <= $num_pre_args; $k++) + { + print "PreArg$k"; + print ", " if ($k < $num_pre_args); + } + print ")"; + for ($k = 1; $k <= $num_pre_args; $k++) + { + print "\n , typename ParamTraits::ForwardType pa$k"; + } + print ") {\n"; + + if ($type eq "Method") + { + print " return new MethodClosure_Bind${num_pre_args}<$self_deleting, ClassPointer, MethodClass"; + } + else + { + print " return new FunctionClosure_Bind${num_pre_args}<$self_deleting"; + } + for ($k = 1; $k <= $num_pre_args; $k++) + { + print ", PreArg$k"; + } + print ">("; + if ($type eq "Method") + { + print "object, method"; + } + else + { + print "function"; + } + for ($k = 1; $k <= $num_pre_args; $k++) + { + print ", pa$k"; + } + print ");\n}\n\n"; + } +} + +# Start real work +PrintHead(); +PrintClosureBase(); +PrintAllClosure_Binds("Method"); +PrintAllClosure_Binds("Function"); +PrintNewClosure("Method", "true"); +PrintNewClosure("Method", "false"); +PrintNewClosure("Function", "true"); +PrintNewClosure("Function", "false"); +PrintEnd(); + diff --git a/src/sofa/pbrpc/closure_helper.h b/src/sofa/pbrpc/closure_helper.h new file mode 100644 index 0000000..b9f720d --- /dev/null +++ b/src/sofa/pbrpc/closure_helper.h @@ -0,0 +1,63 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_CLOSURE_HELPER_H_ +#define _SOFA_PBRPC_CLOSURE_HELPER_H_ + +namespace sofa { +namespace pbrpc { + +template +inline T * get_pointer(T * p) +{ + return p; +} + +// delete p in dtor automatically if Enabled is true +template +class ConditionalAutoDeleter +{ +public: + explicit ConditionalAutoDeleter(T* p) + : m_p(p) + { + } + ~ConditionalAutoDeleter() + { + if (Enabled) + { + delete m_p; + } + } +private: + ConditionalAutoDeleter(const ConditionalAutoDeleter&); + ConditionalAutoDeleter& operator=(const ConditionalAutoDeleter&); +private: + T* m_p; +}; + +// This is a typetraits object that's used to take an argument type, and +// extract a suitable type for storing and forwarding arguments. +template +struct ParamTraits +{ + typedef const T& ForwardType; + typedef T StorageType; +}; + +template +struct ParamTraits +{ + typedef T& ForwardType; + typedef T StorageType; +}; + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_CLOSURE_HELPER_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/common.cc b/src/sofa/pbrpc/common.cc new file mode 100644 index 0000000..273865b --- /dev/null +++ b/src/sofa/pbrpc/common.cc @@ -0,0 +1,61 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include +#include +#include + +#include +#include + +namespace sofa { +namespace pbrpc { +namespace internal { + +static LogLevel s_log_level = ::sofa::pbrpc::LOG_LEVEL_ERROR; + +LogLevel get_log_level() +{ + return s_log_level; +} + +void set_log_level(LogLevel level) +{ + s_log_level = level; +} + +void log_handler(LogLevel level, const char* filename, int line, const char *fmt, ...) +{ + static const char* level_names[] = { "FATAL", "ERROR", "WARNNING", + "INFO", "TRACE", "DEBUG" }; + char buf[1024]; + va_list ap; + va_start(ap, fmt); + vsnprintf(buf, 1024, fmt, ap); + va_end(ap); +#if 0 + fprintf(stderr, "libsofa_pbrpc %s %s %s:%d] %s\n", + level_names[level], + boost::posix_time::to_simple_string( + boost::posix_time::microsec_clock::local_time()).c_str(), + filename, line, buf); +#endif + fprintf(stderr, "libsofa_pbrpc %s %s:%d] %s\n", + level_names[level], + filename, line, buf); + fflush(stderr); + + if (level == ::sofa::pbrpc::LOG_LEVEL_FATAL) + { + abort(); + } +} + +} // namespace internal +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/common.h b/src/sofa/pbrpc/common.h new file mode 100644 index 0000000..fa7d015 --- /dev/null +++ b/src/sofa/pbrpc/common.h @@ -0,0 +1,100 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_COMMON_H_ +#define _SOFA_PBRPC_COMMON_H_ + +#include +#include + +namespace std {} + +namespace sofa { +namespace pbrpc { + +/////////////// types ///////////// +typedef ::google::protobuf::uint uint; + +typedef ::google::protobuf::int8 int8; +typedef ::google::protobuf::int16 int16; +typedef ::google::protobuf::int32 int32; +typedef ::google::protobuf::int64 int64; + +typedef ::google::protobuf::uint8 uint8; +typedef ::google::protobuf::uint16 uint16; +typedef ::google::protobuf::uint32 uint32; +typedef ::google::protobuf::uint64 uint64; + +static const int32 kint32max = ::google::protobuf::kint32max; +static const int32 kint32min = ::google::protobuf::kint32min; +static const int64 kint64max = ::google::protobuf::kint64max; +static const int64 kint64min = ::google::protobuf::kint64min; +static const uint32 kuint32max = ::google::protobuf::kuint32max; +static const uint64 kuint64max = ::google::protobuf::kuint64max; + +/////////////// util macros ///////////// +#define SOFA_PBRPC_PP_CAT(a, b) SOFA_PBRPC_PP_CAT_I(a, b) +#define SOFA_PBRPC_PP_CAT_I(a, b) a ## b + +#define SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(TypeName) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) + +/////////////// logging and check ///////////// +// default log level: ERROR +enum LogLevel { + LOG_LEVEL_FATAL = 0, + LOG_LEVEL_ERROR = 1, + LOG_LEVEL_WARNING = 2, + LOG_LEVEL_NOTICE = 3, + LOG_LEVEL_INFO = 3, + LOG_LEVEL_TRACE = 4, + LOG_LEVEL_DEBUG = 5, +}; + +namespace internal { +LogLevel get_log_level(); +void set_log_level(LogLevel level); +void log_handler(LogLevel level, const char* filename, int line, const char *fmt, ...); +} // namespace internal + +#define SOFA_PBRPC_SET_LOG_LEVEL(level) \ + ::sofa::pbrpc::internal::set_log_level(::sofa::pbrpc::LOG_LEVEL_##level) + +#define SLOG(level, fmt, arg...) \ + (::sofa::pbrpc::LOG_LEVEL_##level > ::sofa::pbrpc::internal::get_log_level()) ? \ + (void)0 : ::sofa::pbrpc::internal::log_handler( \ + ::sofa::pbrpc::LOG_LEVEL_##level, __FILE__, __LINE__, fmt, ##arg) \ + +#define SLOG_IF(condition, level, fmt, arg...) \ + !(condition) ? (void)0 : ::sofa::pbrpc::internal::log_handler( \ + ::sofa::pbrpc::LOG_LEVEL_##level, __FILE__, __LINE__, fmt, ##arg) + +#if defined( LOG ) +#define SCHECK(expression) CHECK(expression) +#define SCHECK_EQ(a, b) CHECK_EQ(a, b) +#define SCHECK_NE(a, b) CHECK_NE(a, b) +#define SCHECK_LT(a, b) CHECK_LT(a, b) +#define SCHECK_LE(a, b) CHECK_LE(a, b) +#define SCHECK_GT(a, b) CHECK_GT(a, b) +#define SCHECK_GE(a, b) CHECK_GE(a, b) +#else +#define SCHECK(expression) \ + SLOG_IF(!(expression), FATAL, "CHECK failed: " #expression) +#define SCHECK_EQ(a, b) SCHECK((a) == (b)) +#define SCHECK_NE(a, b) SCHECK((a) != (b)) +#define SCHECK_LT(a, b) SCHECK((a) < (b)) +#define SCHECK_LE(a, b) SCHECK((a) <= (b)) +#define SCHECK_GT(a, b) SCHECK((a) > (b)) +#define SCHECK_GE(a, b) SCHECK((a) >= (b)) +#endif + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_COMMON_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/common_internal.cc b/src/sofa/pbrpc/common_internal.cc new file mode 100644 index 0000000..e1d022e --- /dev/null +++ b/src/sofa/pbrpc/common_internal.cc @@ -0,0 +1,18 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include + +namespace sofa { +namespace pbrpc { + +SOFA_PBRPC_DEFINE_RESOURCE_COUNTER(RpcByteStream); +SOFA_PBRPC_DEFINE_RESOURCE_COUNTER(RpcListener); + +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/common_internal.h b/src/sofa/pbrpc/common_internal.h new file mode 100644 index 0000000..89f4ac7 --- /dev/null +++ b/src/sofa/pbrpc/common_internal.h @@ -0,0 +1,87 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_COMMON_INTERNAL_H_ +#define _SOFA_PBRPC_COMMON_INTERNAL_H_ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace sofa { +namespace pbrpc { + +class RpcControllerImpl; +typedef sofa::pbrpc::shared_ptr RpcControllerImplPtr; +typedef sofa::pbrpc::weak_ptr RpcControllerImplWPtr; + +class RpcChannelImpl; +typedef sofa::pbrpc::shared_ptr RpcChannelImplPtr; + +class RpcClientImpl; +typedef sofa::pbrpc::shared_ptr RpcClientImplPtr; + +class RpcServerImpl; +typedef sofa::pbrpc::shared_ptr RpcServerImplPtr; +typedef sofa::pbrpc::weak_ptr RpcServerImplWPtr; + +class RpcClientStream; +typedef sofa::pbrpc::shared_ptr RpcClientStreamPtr; +typedef sofa::pbrpc::weak_ptr RpcClientStreamWPtr; + +class RpcServerStream; +typedef sofa::pbrpc::shared_ptr RpcServerStreamPtr; +typedef sofa::pbrpc::weak_ptr RpcServerStreamWPtr; + +class RpcListener; +typedef sofa::pbrpc::shared_ptr RpcListenerPtr; + +class TimerWorker; +typedef sofa::pbrpc::shared_ptr TimerWorkerPtr; + +class RpcTimeoutManager; +typedef sofa::pbrpc::shared_ptr RpcTimeoutManagerPtr; + +class ThreadGroup; +typedef sofa::pbrpc::shared_ptr ThreadGroupPtr; + +class ServicePool; +typedef sofa::pbrpc::shared_ptr ServicePoolPtr; +typedef sofa::pbrpc::weak_ptr ServicePoolWPtr; + +class FlowController; +typedef sofa::pbrpc::shared_ptr FlowControllerPtr; + +class WaitEvent; +typedef sofa::pbrpc::shared_ptr WaitEventPtr; + +#define SOFA_PBRPC_DECLARE_RESOURCE_COUNTER(name_) \ + extern sofa::pbrpc::AtomicCounter g_sofa_counter_##name_ +#define SOFA_PBRPC_DEFINE_RESOURCE_COUNTER(name_) \ + sofa::pbrpc::AtomicCounter g_sofa_counter_##name_(0) +#define SOFA_PBRPC_INC_RESOURCE_COUNTER(name_) \ + ++g_sofa_counter_##name_ +#define SOFA_PBRPC_DEC_RESOURCE_COUNTER(name_) \ + --g_sofa_counter_##name_ +#define SOFA_PBRPC_GET_RESOURCE_COUNTER(name_) \ + static_cast(g_sofa_counter_##name_) + +SOFA_PBRPC_DECLARE_RESOURCE_COUNTER(RpcByteStream); +SOFA_PBRPC_DECLARE_RESOURCE_COUNTER(RpcListener); + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_COMMON_INTERNAL_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/compressed_stream.cc b/src/sofa/pbrpc/compressed_stream.cc new file mode 100644 index 0000000..a0f6675 --- /dev/null +++ b/src/sofa/pbrpc/compressed_stream.cc @@ -0,0 +1,77 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from `protobuf-zerocopy-compression': +// https://github.com/JohannesEbke/protobuf-zerocopy-compression +// +// Copyright (c) 2013, Johannes Ebke and Peter Waller. All rights reserved. +// Author: peter.waller@gmail.com (Peter Waller) +// Author: johannes@ebke.org (Johannes Ebke) + +#include +#include +#include +#include + +namespace sofa { +namespace pbrpc { + +AbstractCompressedInputStream * get_compressed_input_stream( + ZeroCopyInputStream * istream, CompressType type) { + switch(type) { + case CompressTypeGzip: + return new GzipInputStream(istream, GzipInputStream::GZIP); + case CompressTypeZlib: + return new GzipInputStream(istream, GzipInputStream::ZLIB); + case CompressTypeSnappy: +#ifdef HAVE_SNAPPY + return new SnappyInputStream(istream); +#else + SCHECK(false); +#endif + case CompressTypeLZ4: + return new LZ4InputStream(istream); + default: + SCHECK(false); + } + return NULL; +} + +AbstractCompressedOutputStream * get_compressed_output_stream( + ZeroCopyOutputStream * ostream, CompressType type, int level) { + switch (type) { + case CompressTypeGzip: + { + GzipOutputStream::Options o; + o.format = GzipOutputStream::GZIP; + o.compression_level = level; + return new GzipOutputStream(ostream, o); + } + case CompressTypeZlib: + { + GzipOutputStream::Options o; + o.format = GzipOutputStream::ZLIB; + o.compression_level = level; + return new GzipOutputStream(ostream, o); + } + case CompressTypeSnappy: +#ifdef HAVE_SNAPPY + return new SnappyOutputStream(ostream); +#else + SCHECK(false); +#endif + case CompressTypeLZ4: + return new LZ4OutputStream(ostream); + default: + SCHECK(false); + } + return NULL; +} + +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/compressed_stream.h b/src/sofa/pbrpc/compressed_stream.h new file mode 100644 index 0000000..7616f62 --- /dev/null +++ b/src/sofa/pbrpc/compressed_stream.h @@ -0,0 +1,67 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from `protobuf-zerocopy-compression': +// https://github.com/JohannesEbke/protobuf-zerocopy-compression +// +// Copyright (c) 2013, Johannes Ebke and Peter Waller. All rights reserved. +// Author: peter.waller@gmail.com (Peter Waller) +// Author: johannes@ebke.org (Johannes Ebke) + +#ifndef _SOFA_PBRPC_COMPRESSION_COMPRESSED_STREAM_H_ +#define _SOFA_PBRPC_COMPRESSION_COMPRESSED_STREAM_H_ + +#include + +#include + +#define HAVE_SNAPPY 1 + +namespace sofa { +namespace pbrpc { + +/// Base class for all compressed output streams with additional methods +class AbstractCompressedOutputStream : public google::protobuf::io::ZeroCopyOutputStream { +public: + /// Make sure that all data is compressed and written + virtual bool Flush() = 0; + virtual bool Close() = 0; +}; + +/// Base class for all compressed input streams with an ExpectAtEnd method. +class AbstractCompressedInputStream : public google::protobuf::io::ZeroCopyInputStream { +public: + /// ExpectAtEnd returns true if there is no more compressed data to process + virtual bool ExpectAtEnd() = 0; +}; + +///////////////////////////////////////////////// +// Compress type defined in `rpc_option.proto': +// enum CompressType { +// CompressTypeNone = 0; +// CompressTypeGzip = 1; +// CompressTypeZlib = 2; +// CompressTypeSnappy = 3; +// CompressTypeLZ4 = 4; +// } +///////////////////////////////////////////////// + +/// Get a pointer to a compressed output stream given an underlying ZeroCopyOutputStream. +/// Specify any of the above compression types, and a compression level (for use in ZLIB). +AbstractCompressedOutputStream * get_compressed_output_stream( + google::protobuf::io::ZeroCopyOutputStream * ostream, CompressType type, int level=1); + +/// Get a pointer to a compressed input stream given an underlying ZeroCopyInputStream. +/// Specify any of the above compression types. +AbstractCompressedInputStream * get_compressed_input_stream( + google::protobuf::io::ZeroCopyInputStream * istream, CompressType type); + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_COMPRESSION_COMPRESSED_STREAM_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/condition_variable.h b/src/sofa/pbrpc/condition_variable.h new file mode 100644 index 0000000..91d51f5 --- /dev/null +++ b/src/sofa/pbrpc/condition_variable.h @@ -0,0 +1,84 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_CONDITION_VARIABLE_H_ +#define _SOFA_PBRPC_CONDITION_VARIABLE_H_ + +#include +#include +#include + +#include +#include + +namespace sofa { +namespace pbrpc { + +class ConditionVariable +{ +public: + ConditionVariable() + { + pthread_cond_init(&_cond, NULL); + } + ~ConditionVariable() + { + pthread_cond_destroy(&_cond); + } + void wait(MutexLock& mutex) + { + SCHECK_EQ(0, pthread_cond_wait(&_cond, &mutex._lock)); + } + bool wait(MutexLock& mutex, int64 timeout_in_ms) + { + if (timeout_in_ms < 0) + { + wait(mutex); + return true; + } + timespec ts; + calculate_expiration(timeout_in_ms, &ts); + int error = pthread_cond_timedwait(&_cond, &mutex._lock, &ts); + if (error == 0) + { + return true; + } + else if (error == ETIMEDOUT) + { + return false; + } + else + { + SLOG(FATAL, "error no: %d", error); + } + } + void signal() + { + SCHECK_EQ(0, pthread_cond_signal(&_cond)); + } + void broadcast() + { + SCHECK_EQ(0, pthread_cond_broadcast(&_cond)); + } +private: + void calculate_expiration(int64 timeout_in_ms, timespec* ts) + { + timeval tv; + gettimeofday(&tv, NULL); + int64 usec = tv.tv_usec + timeout_in_ms * 1000LL; + ts->tv_sec = tv.tv_sec + usec / 1000000; + ts->tv_nsec = (usec % 1000000) * 1000; + } +private: + pthread_cond_t _cond; +}; + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_CONDITION_VARIABLE_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/counter.h b/src/sofa/pbrpc/counter.h new file mode 100644 index 0000000..9d0a3ae --- /dev/null +++ b/src/sofa/pbrpc/counter.h @@ -0,0 +1,83 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_COUNTER_H_ +#define _SOFA_PBRPC_COUNTER_H_ + +#include + +namespace sofa { +namespace pbrpc { + +class BasicCounter +{ +public: + BasicCounter() : _counter(0) {} + BasicCounter(uint32_t init) : _counter(init) {} + uint32_t operator ++ () + { + return ++ _counter; + } + uint32_t operator -- () + { + return -- _counter; + } + operator uint32_t () const + { + return _counter; + } +private: + uint32_t _counter; +}; + +class AtomicCounter +{ +public: + AtomicCounter() : _counter(0) {} + AtomicCounter(uint32_t init) : _counter(init) {} + uint32_t operator ++ () + { + return atomic_inc_ret_old(&_counter) + 1U; + } + uint32_t operator -- () + { + return atomic_dec_ret_old(&_counter) - 1U; + } + operator uint32_t () const + { + return _counter; + } +private: + volatile uint32_t _counter; +}; + +class AtomicCounter64 +{ +public: + AtomicCounter64() : _counter(0) {} + AtomicCounter64(uint64_t init) : _counter(init) {} + uint64_t operator ++ () + { + return atomic_inc_ret_old64(&_counter) + 1LU; + } + uint64_t operator -- () + { + return atomic_dec_ret_old64(&_counter) - 1LU; + } + operator uint64_t () const + { + return _counter; + } +private: + volatile uint64_t _counter; +}; + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_COUNTER_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/ext_closure.h b/src/sofa/pbrpc/ext_closure.h new file mode 100644 index 0000000..fb5a85a --- /dev/null +++ b/src/sofa/pbrpc/ext_closure.h @@ -0,0 +1,13629 @@ +#ifndef _SOFA_PBRPC_EXT_CLOSURE_H_ +#define _SOFA_PBRPC_EXT_CLOSURE_H_ + +///////////////////////////////////////////////////// +// DO NOT EDIT!!! +// this header file is auto generated by perl script +// edit the generator if necessary +///////////////////////////////////////////////////// + +///////////////////////////////////////////////////// +// Support: +// 1, Support pre-bind and post-bind for general +// function and class method, up to 10 arguments. +// 2, Support pass argument by reference, though bind +// always by value. +// 3, When bind class method, support use +// "sofa::pbrpc::shared_ptr" as this pointer of class. +// 4, Support create temporary and permanent closure: +// Temporary closure (self destoryed after call): +// NewExtClosure(); +// Permanent closure (do not destoryed by self): +// NewPermanentExtClosure(); +///////////////////////////////////////////////////// + +///////////////////////////////////////////////////// +// Usage: +// 1, General function: +// +// void f1(int pre_arg, double post_arg); +// +// ExtClosure* c1 = NewExtClosure(&f1, 1); +// c1->Run(2.0); +// +// ExtClosure* c2 = NewPermanentExtClosure(&f1, 1); +// c2->Run(2.0); +// +// 2, Class method: +// +// class C1 +// { +// public: +// int m1(int pre_arg, double post_arg); +// }; +// +// C1 obj; +// +// ExtClosure* c3 = NewExtClosure(&obj, &C1::m1, 1); +// c3->Run(2.0); +// +// ExtClosure* c4 = NewPermanentExtClosure(&obj, &C1::m1, 1); +// c4->Run(2.0); +// +// class C2 : public sofa::pbrpc::enable_shared_from_this +// { +// public: +// int m1(int pre_arg, double post_arg); +// +// void m2() +// { +// ExtClosure* c7 = NewExtClosure( +// shared_from_this(), &C2::m1, 1); +// c7->Run(2.0); +// +// ExtClosure* c8 = NewPermanentExtClosure( +// shared_from_this(), &C2::m1, 1); +// c8->Run(2.0); +// } +// }; +// +///////////////////////////////////////////////////// + +///////////////////////////////////////////////////// +// +// //////// ExtClosure without return type //////// +// ExtClosure: x->Run(), ExtClosure can pre-bind 0~10 argument(s). +// ExtClosure: x->Run(arg1), ExtClosure can pre-bind 0~10 argument(s). +// ExtClosure: x->Run(arg1, arg2), ExtClosure can pre-bind 0~10 argument(s). +// ExtClosure: x->Run(arg1, arg2, arg3), ExtClosure can pre-bind 0~10 argument(s). +// ExtClosure: x->Run(arg1, arg2, arg3, arg4), ExtClosure can pre-bind 0~10 argument(s). +// ExtClosure: x->Run(arg1, arg2, arg3, arg4, arg5), ExtClosure can pre-bind 0~10 argument(s). +// ExtClosure: x->Run(arg1, arg2, arg3, arg4, arg5, arg6), ExtClosure can pre-bind 0~10 argument(s). +// ExtClosure: x->Run(arg1, arg2, arg3, arg4, arg5, arg6, arg7), ExtClosure can pre-bind 0~10 argument(s). +// ExtClosure: x->Run(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8), ExtClosure can pre-bind 0~10 argument(s). +// ExtClosure: x->Run(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9), ExtClosure can pre-bind 0~10 argument(s). +// ExtClosure: x->Run(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10), ExtClosure can pre-bind 0~10 argument(s). +// +// /////// ExtClosure with return type of R /////// +// ExtClosure: R = x->Run(), ExtClosure can pre-bind 0~10 argument(s). +// ExtClosure: R = x->Run(arg1), ExtClosure can pre-bind 0~10 argument(s). +// ExtClosure: R = x->Run(arg1, arg2), ExtClosure can pre-bind 0~10 argument(s). +// ExtClosure: R = x->Run(arg1, arg2, arg3), ExtClosure can pre-bind 0~10 argument(s). +// ExtClosure: R = x->Run(arg1, arg2, arg3, arg4), ExtClosure can pre-bind 0~10 argument(s). +// ExtClosure: R = x->Run(arg1, arg2, arg3, arg4, arg5), ExtClosure can pre-bind 0~10 argument(s). +// ExtClosure: R = x->Run(arg1, arg2, arg3, arg4, arg5, arg6), ExtClosure can pre-bind 0~10 argument(s). +// ExtClosure: R = x->Run(arg1, arg2, arg3, arg4, arg5, arg6, arg7), ExtClosure can pre-bind 0~10 argument(s). +// ExtClosure: R = x->Run(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8), ExtClosure can pre-bind 0~10 argument(s). +// ExtClosure: R = x->Run(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9), ExtClosure can pre-bind 0~10 argument(s). +// ExtClosure: R = x->Run(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10), ExtClosure can pre-bind 0~10 argument(s). +// +///////////////////////////////////////////////////// + +#include + +namespace sofa { +namespace pbrpc{ + +/// base class for all ExtClosures +class ExtClosureBase +{ +public: + virtual ~ExtClosureBase() {} + virtual bool IsSelfDelete() const = 0; +}; + +// primary template +template class ExtClosure : public ExtClosureBase +{ +}; + +// specified for 0 argument +template < + typename R +> +class ExtClosure + : public ExtClosureBase +{ +public: + virtual R Run() = 0; +}; + +// specified for 1 argument +template < + typename R, + typename Arg1 +> +class ExtClosure + : public ExtClosureBase +{ +public: + virtual R Run(Arg1 arg1) = 0; +}; + +// specified for 2 arguments +template < + typename R, + typename Arg1, + typename Arg2 +> +class ExtClosure + : public ExtClosureBase +{ +public: + virtual R Run(Arg1 arg1, Arg2 arg2) = 0; +}; + +// specified for 3 arguments +template < + typename R, + typename Arg1, + typename Arg2, + typename Arg3 +> +class ExtClosure + : public ExtClosureBase +{ +public: + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) = 0; +}; + +// specified for 4 arguments +template < + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class ExtClosure + : public ExtClosureBase +{ +public: + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) = 0; +}; + +// specified for 5 arguments +template < + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class ExtClosure + : public ExtClosureBase +{ +public: + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) = 0; +}; + +// specified for 6 arguments +template < + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class ExtClosure + : public ExtClosureBase +{ +public: + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) = 0; +}; + +// specified for 7 arguments +template < + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class ExtClosure + : public ExtClosureBase +{ +public: + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) = 0; +}; + +// specified for 8 arguments +template < + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class ExtClosure + : public ExtClosureBase +{ +public: + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) = 0; +}; + +// specified for 9 arguments +template < + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class ExtClosure + : public ExtClosureBase +{ +public: + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) = 0; +}; + +// specified for 10 arguments +template < + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class ExtClosure + : public ExtClosureBase +{ +public: + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) = 0; +}; + +// specified for 11 arguments +template < + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10, + typename Arg11 +> +class ExtClosure + : public ExtClosureBase +{ +public: + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10, Arg11 arg11) = 0; +}; + +// specified for 12 arguments +template < + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10, + typename Arg11, + typename Arg12 +> +class ExtClosure + : public ExtClosureBase +{ +public: + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10, Arg11 arg11, Arg12 arg12) = 0; +}; + +// specified for 13 arguments +template < + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10, + typename Arg11, + typename Arg12, + typename Arg13 +> +class ExtClosure + : public ExtClosureBase +{ +public: + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10, Arg11 arg11, Arg12 arg12, Arg13 arg13) = 0; +}; + +// specified for 14 arguments +template < + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10, + typename Arg11, + typename Arg12, + typename Arg13, + typename Arg14 +> +class ExtClosure + : public ExtClosureBase +{ +public: + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10, Arg11 arg11, Arg12 arg12, Arg13 arg13, Arg14 arg14) = 0; +}; + +// specified for 15 arguments +template < + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10, + typename Arg11, + typename Arg12, + typename Arg13, + typename Arg14, + typename Arg15 +> +class ExtClosure + : public ExtClosureBase +{ +public: + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10, Arg11 arg11, Arg12 arg12, Arg13 arg13, Arg14 arg14, Arg15 arg15) = 0; +}; + +// specified for 16 arguments +template < + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10, + typename Arg11, + typename Arg12, + typename Arg13, + typename Arg14, + typename Arg15, + typename Arg16 +> +class ExtClosure + : public ExtClosureBase +{ +public: + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10, Arg11 arg11, Arg12 arg12, Arg13 arg13, Arg14 arg14, Arg15 arg15, Arg16 arg16) = 0; +}; + +// specified for 17 arguments +template < + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10, + typename Arg11, + typename Arg12, + typename Arg13, + typename Arg14, + typename Arg15, + typename Arg16, + typename Arg17 +> +class ExtClosure + : public ExtClosureBase +{ +public: + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10, Arg11 arg11, Arg12 arg12, Arg13 arg13, Arg14 arg14, Arg15 arg15, Arg16 arg16, Arg17 arg17) = 0; +}; + +// specified for 18 arguments +template < + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10, + typename Arg11, + typename Arg12, + typename Arg13, + typename Arg14, + typename Arg15, + typename Arg16, + typename Arg17, + typename Arg18 +> +class ExtClosure + : public ExtClosureBase +{ +public: + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10, Arg11 arg11, Arg12 arg12, Arg13 arg13, Arg14 arg14, Arg15 arg15, Arg16 arg16, Arg17 arg17, Arg18 arg18) = 0; +}; + +// specified for 19 arguments +template < + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10, + typename Arg11, + typename Arg12, + typename Arg13, + typename Arg14, + typename Arg15, + typename Arg16, + typename Arg17, + typename Arg18, + typename Arg19 +> +class ExtClosure + : public ExtClosureBase +{ +public: + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10, Arg11 arg11, Arg12 arg12, Arg13 arg13, Arg14 arg14, Arg15 arg15, Arg16 arg16, Arg17 arg17, Arg18 arg18, Arg19 arg19) = 0; +}; +//////////////////////////////////////////////////// +//////////// class method closures ///////////////// +//////////////////////////////////////////////////// + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass +> +class MethodExtClosure_Arg0_Bind0 : public ExtClosure { + typedef R (MethodClass::*MethodType)(); +public: + MethodExtClosure_Arg0_Bind0(ClassPointer object, MethodType method): + m_object(object), m_method(method) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1 +> +class MethodExtClosure_Arg0_Bind1 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1); +public: + MethodExtClosure_Arg0_Bind1(ClassPointer object, MethodType method, PreArg1 pa1): + m_object(object), m_method(method), m_pa1(pa1) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2 +> +class MethodExtClosure_Arg0_Bind2 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2); +public: + MethodExtClosure_Arg0_Bind2(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3 +> +class MethodExtClosure_Arg0_Bind3 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3); +public: + MethodExtClosure_Arg0_Bind3(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4 +> +class MethodExtClosure_Arg0_Bind4 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4); +public: + MethodExtClosure_Arg0_Bind4(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5 +> +class MethodExtClosure_Arg0_Bind5 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5); +public: + MethodExtClosure_Arg0_Bind5(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6 +> +class MethodExtClosure_Arg0_Bind6 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6); +public: + MethodExtClosure_Arg0_Bind6(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7 +> +class MethodExtClosure_Arg0_Bind7 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7); +public: + MethodExtClosure_Arg0_Bind7(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8 +> +class MethodExtClosure_Arg0_Bind8 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8); +public: + MethodExtClosure_Arg0_Bind8(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9 +> +class MethodExtClosure_Arg0_Bind9 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9); +public: + MethodExtClosure_Arg0_Bind9(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10 +> +class MethodExtClosure_Arg0_Bind10 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10); +public: + MethodExtClosure_Arg0_Bind10(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename Arg1 +> +class MethodExtClosure_Arg1_Bind0 : public ExtClosure { + typedef R (MethodClass::*MethodType)(Arg1); +public: + MethodExtClosure_Arg1_Bind0(ClassPointer object, MethodType method): + m_object(object), m_method(method) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename Arg1 +> +class MethodExtClosure_Arg1_Bind1 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, Arg1); +public: + MethodExtClosure_Arg1_Bind1(ClassPointer object, MethodType method, PreArg1 pa1): + m_object(object), m_method(method), m_pa1(pa1) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename Arg1 +> +class MethodExtClosure_Arg1_Bind2 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, Arg1); +public: + MethodExtClosure_Arg1_Bind2(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename Arg1 +> +class MethodExtClosure_Arg1_Bind3 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, Arg1); +public: + MethodExtClosure_Arg1_Bind3(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename Arg1 +> +class MethodExtClosure_Arg1_Bind4 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1); +public: + MethodExtClosure_Arg1_Bind4(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename Arg1 +> +class MethodExtClosure_Arg1_Bind5 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1); +public: + MethodExtClosure_Arg1_Bind5(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename Arg1 +> +class MethodExtClosure_Arg1_Bind6 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1); +public: + MethodExtClosure_Arg1_Bind6(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename Arg1 +> +class MethodExtClosure_Arg1_Bind7 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1); +public: + MethodExtClosure_Arg1_Bind7(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename Arg1 +> +class MethodExtClosure_Arg1_Bind8 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1); +public: + MethodExtClosure_Arg1_Bind8(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename Arg1 +> +class MethodExtClosure_Arg1_Bind9 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1); +public: + MethodExtClosure_Arg1_Bind9(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10, + typename Arg1 +> +class MethodExtClosure_Arg1_Bind10 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1); +public: + MethodExtClosure_Arg1_Bind10(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10, arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename Arg1, + typename Arg2 +> +class MethodExtClosure_Arg2_Bind0 : public ExtClosure { + typedef R (MethodClass::*MethodType)(Arg1, Arg2); +public: + MethodExtClosure_Arg2_Bind0(ClassPointer object, MethodType method): + m_object(object), m_method(method) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename Arg1, + typename Arg2 +> +class MethodExtClosure_Arg2_Bind1 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, Arg1, Arg2); +public: + MethodExtClosure_Arg2_Bind1(ClassPointer object, MethodType method, PreArg1 pa1): + m_object(object), m_method(method), m_pa1(pa1) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename Arg1, + typename Arg2 +> +class MethodExtClosure_Arg2_Bind2 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, Arg1, Arg2); +public: + MethodExtClosure_Arg2_Bind2(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename Arg1, + typename Arg2 +> +class MethodExtClosure_Arg2_Bind3 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, Arg1, Arg2); +public: + MethodExtClosure_Arg2_Bind3(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename Arg1, + typename Arg2 +> +class MethodExtClosure_Arg2_Bind4 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2); +public: + MethodExtClosure_Arg2_Bind4(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename Arg1, + typename Arg2 +> +class MethodExtClosure_Arg2_Bind5 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2); +public: + MethodExtClosure_Arg2_Bind5(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename Arg1, + typename Arg2 +> +class MethodExtClosure_Arg2_Bind6 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2); +public: + MethodExtClosure_Arg2_Bind6(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename Arg1, + typename Arg2 +> +class MethodExtClosure_Arg2_Bind7 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2); +public: + MethodExtClosure_Arg2_Bind7(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename Arg1, + typename Arg2 +> +class MethodExtClosure_Arg2_Bind8 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2); +public: + MethodExtClosure_Arg2_Bind8(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename Arg1, + typename Arg2 +> +class MethodExtClosure_Arg2_Bind9 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2); +public: + MethodExtClosure_Arg2_Bind9(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10, + typename Arg1, + typename Arg2 +> +class MethodExtClosure_Arg2_Bind10 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2); +public: + MethodExtClosure_Arg2_Bind10(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10, arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename Arg1, + typename Arg2, + typename Arg3 +> +class MethodExtClosure_Arg3_Bind0 : public ExtClosure { + typedef R (MethodClass::*MethodType)(Arg1, Arg2, Arg3); +public: + MethodExtClosure_Arg3_Bind0(ClassPointer object, MethodType method): + m_object(object), m_method(method) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename Arg1, + typename Arg2, + typename Arg3 +> +class MethodExtClosure_Arg3_Bind1 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, Arg1, Arg2, Arg3); +public: + MethodExtClosure_Arg3_Bind1(ClassPointer object, MethodType method, PreArg1 pa1): + m_object(object), m_method(method), m_pa1(pa1) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename Arg1, + typename Arg2, + typename Arg3 +> +class MethodExtClosure_Arg3_Bind2 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, Arg1, Arg2, Arg3); +public: + MethodExtClosure_Arg3_Bind2(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename Arg1, + typename Arg2, + typename Arg3 +> +class MethodExtClosure_Arg3_Bind3 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3); +public: + MethodExtClosure_Arg3_Bind3(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename Arg1, + typename Arg2, + typename Arg3 +> +class MethodExtClosure_Arg3_Bind4 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3); +public: + MethodExtClosure_Arg3_Bind4(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename Arg1, + typename Arg2, + typename Arg3 +> +class MethodExtClosure_Arg3_Bind5 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3); +public: + MethodExtClosure_Arg3_Bind5(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename Arg1, + typename Arg2, + typename Arg3 +> +class MethodExtClosure_Arg3_Bind6 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3); +public: + MethodExtClosure_Arg3_Bind6(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename Arg1, + typename Arg2, + typename Arg3 +> +class MethodExtClosure_Arg3_Bind7 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3); +public: + MethodExtClosure_Arg3_Bind7(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename Arg1, + typename Arg2, + typename Arg3 +> +class MethodExtClosure_Arg3_Bind8 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3); +public: + MethodExtClosure_Arg3_Bind8(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename Arg1, + typename Arg2, + typename Arg3 +> +class MethodExtClosure_Arg3_Bind9 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3); +public: + MethodExtClosure_Arg3_Bind9(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10, + typename Arg1, + typename Arg2, + typename Arg3 +> +class MethodExtClosure_Arg3_Bind10 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3); +public: + MethodExtClosure_Arg3_Bind10(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10, arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class MethodExtClosure_Arg4_Bind0 : public ExtClosure { + typedef R (MethodClass::*MethodType)(Arg1, Arg2, Arg3, Arg4); +public: + MethodExtClosure_Arg4_Bind0(ClassPointer object, MethodType method): + m_object(object), m_method(method) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class MethodExtClosure_Arg4_Bind1 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, Arg1, Arg2, Arg3, Arg4); +public: + MethodExtClosure_Arg4_Bind1(ClassPointer object, MethodType method, PreArg1 pa1): + m_object(object), m_method(method), m_pa1(pa1) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class MethodExtClosure_Arg4_Bind2 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4); +public: + MethodExtClosure_Arg4_Bind2(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class MethodExtClosure_Arg4_Bind3 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4); +public: + MethodExtClosure_Arg4_Bind3(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class MethodExtClosure_Arg4_Bind4 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4); +public: + MethodExtClosure_Arg4_Bind4(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class MethodExtClosure_Arg4_Bind5 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4); +public: + MethodExtClosure_Arg4_Bind5(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class MethodExtClosure_Arg4_Bind6 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4); +public: + MethodExtClosure_Arg4_Bind6(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class MethodExtClosure_Arg4_Bind7 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4); +public: + MethodExtClosure_Arg4_Bind7(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class MethodExtClosure_Arg4_Bind8 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4); +public: + MethodExtClosure_Arg4_Bind8(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class MethodExtClosure_Arg4_Bind9 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4); +public: + MethodExtClosure_Arg4_Bind9(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class MethodExtClosure_Arg4_Bind10 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4); +public: + MethodExtClosure_Arg4_Bind10(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10, arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class MethodExtClosure_Arg5_Bind0 : public ExtClosure { + typedef R (MethodClass::*MethodType)(Arg1, Arg2, Arg3, Arg4, Arg5); +public: + MethodExtClosure_Arg5_Bind0(ClassPointer object, MethodType method): + m_object(object), m_method(method) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class MethodExtClosure_Arg5_Bind1 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5); +public: + MethodExtClosure_Arg5_Bind1(ClassPointer object, MethodType method, PreArg1 pa1): + m_object(object), m_method(method), m_pa1(pa1) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class MethodExtClosure_Arg5_Bind2 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5); +public: + MethodExtClosure_Arg5_Bind2(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class MethodExtClosure_Arg5_Bind3 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5); +public: + MethodExtClosure_Arg5_Bind3(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class MethodExtClosure_Arg5_Bind4 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5); +public: + MethodExtClosure_Arg5_Bind4(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class MethodExtClosure_Arg5_Bind5 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5); +public: + MethodExtClosure_Arg5_Bind5(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class MethodExtClosure_Arg5_Bind6 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5); +public: + MethodExtClosure_Arg5_Bind6(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class MethodExtClosure_Arg5_Bind7 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5); +public: + MethodExtClosure_Arg5_Bind7(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class MethodExtClosure_Arg5_Bind8 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5); +public: + MethodExtClosure_Arg5_Bind8(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class MethodExtClosure_Arg5_Bind9 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5); +public: + MethodExtClosure_Arg5_Bind9(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class MethodExtClosure_Arg5_Bind10 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5); +public: + MethodExtClosure_Arg5_Bind10(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10, arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class MethodExtClosure_Arg6_Bind0 : public ExtClosure { + typedef R (MethodClass::*MethodType)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + MethodExtClosure_Arg6_Bind0(ClassPointer object, MethodType method): + m_object(object), m_method(method) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class MethodExtClosure_Arg6_Bind1 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + MethodExtClosure_Arg6_Bind1(ClassPointer object, MethodType method, PreArg1 pa1): + m_object(object), m_method(method), m_pa1(pa1) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class MethodExtClosure_Arg6_Bind2 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + MethodExtClosure_Arg6_Bind2(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class MethodExtClosure_Arg6_Bind3 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + MethodExtClosure_Arg6_Bind3(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class MethodExtClosure_Arg6_Bind4 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + MethodExtClosure_Arg6_Bind4(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class MethodExtClosure_Arg6_Bind5 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + MethodExtClosure_Arg6_Bind5(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class MethodExtClosure_Arg6_Bind6 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + MethodExtClosure_Arg6_Bind6(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class MethodExtClosure_Arg6_Bind7 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + MethodExtClosure_Arg6_Bind7(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class MethodExtClosure_Arg6_Bind8 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + MethodExtClosure_Arg6_Bind8(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class MethodExtClosure_Arg6_Bind9 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + MethodExtClosure_Arg6_Bind9(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class MethodExtClosure_Arg6_Bind10 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + MethodExtClosure_Arg6_Bind10(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10, arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class MethodExtClosure_Arg7_Bind0 : public ExtClosure { + typedef R (MethodClass::*MethodType)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + MethodExtClosure_Arg7_Bind0(ClassPointer object, MethodType method): + m_object(object), m_method(method) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class MethodExtClosure_Arg7_Bind1 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + MethodExtClosure_Arg7_Bind1(ClassPointer object, MethodType method, PreArg1 pa1): + m_object(object), m_method(method), m_pa1(pa1) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class MethodExtClosure_Arg7_Bind2 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + MethodExtClosure_Arg7_Bind2(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class MethodExtClosure_Arg7_Bind3 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + MethodExtClosure_Arg7_Bind3(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class MethodExtClosure_Arg7_Bind4 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + MethodExtClosure_Arg7_Bind4(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class MethodExtClosure_Arg7_Bind5 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + MethodExtClosure_Arg7_Bind5(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class MethodExtClosure_Arg7_Bind6 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + MethodExtClosure_Arg7_Bind6(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class MethodExtClosure_Arg7_Bind7 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + MethodExtClosure_Arg7_Bind7(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class MethodExtClosure_Arg7_Bind8 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + MethodExtClosure_Arg7_Bind8(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class MethodExtClosure_Arg7_Bind9 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + MethodExtClosure_Arg7_Bind9(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class MethodExtClosure_Arg7_Bind10 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + MethodExtClosure_Arg7_Bind10(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class MethodExtClosure_Arg8_Bind0 : public ExtClosure { + typedef R (MethodClass::*MethodType)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + MethodExtClosure_Arg8_Bind0(ClassPointer object, MethodType method): + m_object(object), m_method(method) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class MethodExtClosure_Arg8_Bind1 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + MethodExtClosure_Arg8_Bind1(ClassPointer object, MethodType method, PreArg1 pa1): + m_object(object), m_method(method), m_pa1(pa1) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class MethodExtClosure_Arg8_Bind2 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + MethodExtClosure_Arg8_Bind2(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class MethodExtClosure_Arg8_Bind3 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + MethodExtClosure_Arg8_Bind3(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class MethodExtClosure_Arg8_Bind4 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + MethodExtClosure_Arg8_Bind4(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class MethodExtClosure_Arg8_Bind5 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + MethodExtClosure_Arg8_Bind5(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class MethodExtClosure_Arg8_Bind6 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + MethodExtClosure_Arg8_Bind6(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class MethodExtClosure_Arg8_Bind7 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + MethodExtClosure_Arg8_Bind7(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class MethodExtClosure_Arg8_Bind8 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + MethodExtClosure_Arg8_Bind8(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class MethodExtClosure_Arg8_Bind9 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + MethodExtClosure_Arg8_Bind9(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class MethodExtClosure_Arg8_Bind10 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + MethodExtClosure_Arg8_Bind10(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class MethodExtClosure_Arg9_Bind0 : public ExtClosure { + typedef R (MethodClass::*MethodType)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + MethodExtClosure_Arg9_Bind0(ClassPointer object, MethodType method): + m_object(object), m_method(method) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class MethodExtClosure_Arg9_Bind1 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + MethodExtClosure_Arg9_Bind1(ClassPointer object, MethodType method, PreArg1 pa1): + m_object(object), m_method(method), m_pa1(pa1) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class MethodExtClosure_Arg9_Bind2 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + MethodExtClosure_Arg9_Bind2(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class MethodExtClosure_Arg9_Bind3 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + MethodExtClosure_Arg9_Bind3(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class MethodExtClosure_Arg9_Bind4 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + MethodExtClosure_Arg9_Bind4(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class MethodExtClosure_Arg9_Bind5 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + MethodExtClosure_Arg9_Bind5(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class MethodExtClosure_Arg9_Bind6 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + MethodExtClosure_Arg9_Bind6(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class MethodExtClosure_Arg9_Bind7 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + MethodExtClosure_Arg9_Bind7(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class MethodExtClosure_Arg9_Bind8 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + MethodExtClosure_Arg9_Bind8(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class MethodExtClosure_Arg9_Bind9 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + MethodExtClosure_Arg9_Bind9(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class MethodExtClosure_Arg9_Bind10 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + MethodExtClosure_Arg9_Bind10(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class MethodExtClosure_Arg10_Bind0 : public ExtClosure { + typedef R (MethodClass::*MethodType)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + MethodExtClosure_Arg10_Bind0(ClassPointer object, MethodType method): + m_object(object), m_method(method) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class MethodExtClosure_Arg10_Bind1 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + MethodExtClosure_Arg10_Bind1(ClassPointer object, MethodType method, PreArg1 pa1): + m_object(object), m_method(method), m_pa1(pa1) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class MethodExtClosure_Arg10_Bind2 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + MethodExtClosure_Arg10_Bind2(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class MethodExtClosure_Arg10_Bind3 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + MethodExtClosure_Arg10_Bind3(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class MethodExtClosure_Arg10_Bind4 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + MethodExtClosure_Arg10_Bind4(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class MethodExtClosure_Arg10_Bind5 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + MethodExtClosure_Arg10_Bind5(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class MethodExtClosure_Arg10_Bind6 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + MethodExtClosure_Arg10_Bind6(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class MethodExtClosure_Arg10_Bind7 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + MethodExtClosure_Arg10_Bind7(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class MethodExtClosure_Arg10_Bind8 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + MethodExtClosure_Arg10_Bind8(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class MethodExtClosure_Arg10_Bind9 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + MethodExtClosure_Arg10_Bind9(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename ClassPointer, typename MethodClass, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class MethodExtClosure_Arg10_Bind10 : public ExtClosure { + typedef R (MethodClass::*MethodType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + MethodExtClosure_Arg10_Bind10(ClassPointer object, MethodType method, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_object(object), m_method(method), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return (get_pointer(m_object)->*m_method)(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + ClassPointer m_object; + MethodType m_method; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +//////////////////////////////////////////////////// +//////////// nomal function closures ////////////////// +//////////////////////////////////////////////////// + +template < + bool SelfDeleting, + typename R +> +class FunctionExtClosure_Arg0_Bind0 : public ExtClosure { + typedef R (*FunctionType)(); +public: + FunctionExtClosure_Arg0_Bind0(FunctionType function): + m_function(function) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1 +> +class FunctionExtClosure_Arg0_Bind1 : public ExtClosure { + typedef R (*FunctionType)(PreArg1); +public: + FunctionExtClosure_Arg0_Bind1(FunctionType function, PreArg1 pa1): + m_function(function), m_pa1(pa1) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2 +> +class FunctionExtClosure_Arg0_Bind2 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2); +public: + FunctionExtClosure_Arg0_Bind2(FunctionType function, PreArg1 pa1, PreArg2 pa2): + m_function(function), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3 +> +class FunctionExtClosure_Arg0_Bind3 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3); +public: + FunctionExtClosure_Arg0_Bind3(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4 +> +class FunctionExtClosure_Arg0_Bind4 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4); +public: + FunctionExtClosure_Arg0_Bind4(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5 +> +class FunctionExtClosure_Arg0_Bind5 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5); +public: + FunctionExtClosure_Arg0_Bind5(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6 +> +class FunctionExtClosure_Arg0_Bind6 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6); +public: + FunctionExtClosure_Arg0_Bind6(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7 +> +class FunctionExtClosure_Arg0_Bind7 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7); +public: + FunctionExtClosure_Arg0_Bind7(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8 +> +class FunctionExtClosure_Arg0_Bind8 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8); +public: + FunctionExtClosure_Arg0_Bind8(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9 +> +class FunctionExtClosure_Arg0_Bind9 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9); +public: + FunctionExtClosure_Arg0_Bind9(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10 +> +class FunctionExtClosure_Arg0_Bind10 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10); +public: + FunctionExtClosure_Arg0_Bind10(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run() { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +template < + bool SelfDeleting, + typename R, + typename Arg1 +> +class FunctionExtClosure_Arg1_Bind0 : public ExtClosure { + typedef R (*FunctionType)(Arg1); +public: + FunctionExtClosure_Arg1_Bind0(FunctionType function): + m_function(function) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return m_function(arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename Arg1 +> +class FunctionExtClosure_Arg1_Bind1 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, Arg1); +public: + FunctionExtClosure_Arg1_Bind1(FunctionType function, PreArg1 pa1): + m_function(function), m_pa1(pa1) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename Arg1 +> +class FunctionExtClosure_Arg1_Bind2 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, Arg1); +public: + FunctionExtClosure_Arg1_Bind2(FunctionType function, PreArg1 pa1, PreArg2 pa2): + m_function(function), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename Arg1 +> +class FunctionExtClosure_Arg1_Bind3 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, Arg1); +public: + FunctionExtClosure_Arg1_Bind3(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename Arg1 +> +class FunctionExtClosure_Arg1_Bind4 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1); +public: + FunctionExtClosure_Arg1_Bind4(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename Arg1 +> +class FunctionExtClosure_Arg1_Bind5 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1); +public: + FunctionExtClosure_Arg1_Bind5(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename Arg1 +> +class FunctionExtClosure_Arg1_Bind6 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1); +public: + FunctionExtClosure_Arg1_Bind6(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename Arg1 +> +class FunctionExtClosure_Arg1_Bind7 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1); +public: + FunctionExtClosure_Arg1_Bind7(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename Arg1 +> +class FunctionExtClosure_Arg1_Bind8 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1); +public: + FunctionExtClosure_Arg1_Bind8(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename Arg1 +> +class FunctionExtClosure_Arg1_Bind9 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1); +public: + FunctionExtClosure_Arg1_Bind9(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10, + typename Arg1 +> +class FunctionExtClosure_Arg1_Bind10 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1); +public: + FunctionExtClosure_Arg1_Bind10(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run(Arg1 arg1) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10, arg1); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +template < + bool SelfDeleting, + typename R, + typename Arg1, + typename Arg2 +> +class FunctionExtClosure_Arg2_Bind0 : public ExtClosure { + typedef R (*FunctionType)(Arg1, Arg2); +public: + FunctionExtClosure_Arg2_Bind0(FunctionType function): + m_function(function) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return m_function(arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename Arg1, + typename Arg2 +> +class FunctionExtClosure_Arg2_Bind1 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, Arg1, Arg2); +public: + FunctionExtClosure_Arg2_Bind1(FunctionType function, PreArg1 pa1): + m_function(function), m_pa1(pa1) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename Arg1, + typename Arg2 +> +class FunctionExtClosure_Arg2_Bind2 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, Arg1, Arg2); +public: + FunctionExtClosure_Arg2_Bind2(FunctionType function, PreArg1 pa1, PreArg2 pa2): + m_function(function), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename Arg1, + typename Arg2 +> +class FunctionExtClosure_Arg2_Bind3 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, Arg1, Arg2); +public: + FunctionExtClosure_Arg2_Bind3(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename Arg1, + typename Arg2 +> +class FunctionExtClosure_Arg2_Bind4 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2); +public: + FunctionExtClosure_Arg2_Bind4(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename Arg1, + typename Arg2 +> +class FunctionExtClosure_Arg2_Bind5 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2); +public: + FunctionExtClosure_Arg2_Bind5(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename Arg1, + typename Arg2 +> +class FunctionExtClosure_Arg2_Bind6 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2); +public: + FunctionExtClosure_Arg2_Bind6(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename Arg1, + typename Arg2 +> +class FunctionExtClosure_Arg2_Bind7 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2); +public: + FunctionExtClosure_Arg2_Bind7(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename Arg1, + typename Arg2 +> +class FunctionExtClosure_Arg2_Bind8 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2); +public: + FunctionExtClosure_Arg2_Bind8(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename Arg1, + typename Arg2 +> +class FunctionExtClosure_Arg2_Bind9 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2); +public: + FunctionExtClosure_Arg2_Bind9(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10, + typename Arg1, + typename Arg2 +> +class FunctionExtClosure_Arg2_Bind10 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2); +public: + FunctionExtClosure_Arg2_Bind10(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run(Arg1 arg1, Arg2 arg2) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10, arg1, arg2); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +template < + bool SelfDeleting, + typename R, + typename Arg1, + typename Arg2, + typename Arg3 +> +class FunctionExtClosure_Arg3_Bind0 : public ExtClosure { + typedef R (*FunctionType)(Arg1, Arg2, Arg3); +public: + FunctionExtClosure_Arg3_Bind0(FunctionType function): + m_function(function) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return m_function(arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename Arg1, + typename Arg2, + typename Arg3 +> +class FunctionExtClosure_Arg3_Bind1 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, Arg1, Arg2, Arg3); +public: + FunctionExtClosure_Arg3_Bind1(FunctionType function, PreArg1 pa1): + m_function(function), m_pa1(pa1) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename Arg1, + typename Arg2, + typename Arg3 +> +class FunctionExtClosure_Arg3_Bind2 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, Arg1, Arg2, Arg3); +public: + FunctionExtClosure_Arg3_Bind2(FunctionType function, PreArg1 pa1, PreArg2 pa2): + m_function(function), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename Arg1, + typename Arg2, + typename Arg3 +> +class FunctionExtClosure_Arg3_Bind3 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3); +public: + FunctionExtClosure_Arg3_Bind3(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename Arg1, + typename Arg2, + typename Arg3 +> +class FunctionExtClosure_Arg3_Bind4 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3); +public: + FunctionExtClosure_Arg3_Bind4(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename Arg1, + typename Arg2, + typename Arg3 +> +class FunctionExtClosure_Arg3_Bind5 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3); +public: + FunctionExtClosure_Arg3_Bind5(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename Arg1, + typename Arg2, + typename Arg3 +> +class FunctionExtClosure_Arg3_Bind6 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3); +public: + FunctionExtClosure_Arg3_Bind6(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename Arg1, + typename Arg2, + typename Arg3 +> +class FunctionExtClosure_Arg3_Bind7 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3); +public: + FunctionExtClosure_Arg3_Bind7(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename Arg1, + typename Arg2, + typename Arg3 +> +class FunctionExtClosure_Arg3_Bind8 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3); +public: + FunctionExtClosure_Arg3_Bind8(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename Arg1, + typename Arg2, + typename Arg3 +> +class FunctionExtClosure_Arg3_Bind9 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3); +public: + FunctionExtClosure_Arg3_Bind9(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10, + typename Arg1, + typename Arg2, + typename Arg3 +> +class FunctionExtClosure_Arg3_Bind10 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3); +public: + FunctionExtClosure_Arg3_Bind10(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10, arg1, arg2, arg3); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +template < + bool SelfDeleting, + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class FunctionExtClosure_Arg4_Bind0 : public ExtClosure { + typedef R (*FunctionType)(Arg1, Arg2, Arg3, Arg4); +public: + FunctionExtClosure_Arg4_Bind0(FunctionType function): + m_function(function) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return m_function(arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class FunctionExtClosure_Arg4_Bind1 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, Arg1, Arg2, Arg3, Arg4); +public: + FunctionExtClosure_Arg4_Bind1(FunctionType function, PreArg1 pa1): + m_function(function), m_pa1(pa1) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class FunctionExtClosure_Arg4_Bind2 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4); +public: + FunctionExtClosure_Arg4_Bind2(FunctionType function, PreArg1 pa1, PreArg2 pa2): + m_function(function), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class FunctionExtClosure_Arg4_Bind3 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4); +public: + FunctionExtClosure_Arg4_Bind3(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class FunctionExtClosure_Arg4_Bind4 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4); +public: + FunctionExtClosure_Arg4_Bind4(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class FunctionExtClosure_Arg4_Bind5 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4); +public: + FunctionExtClosure_Arg4_Bind5(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class FunctionExtClosure_Arg4_Bind6 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4); +public: + FunctionExtClosure_Arg4_Bind6(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class FunctionExtClosure_Arg4_Bind7 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4); +public: + FunctionExtClosure_Arg4_Bind7(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class FunctionExtClosure_Arg4_Bind8 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4); +public: + FunctionExtClosure_Arg4_Bind8(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class FunctionExtClosure_Arg4_Bind9 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4); +public: + FunctionExtClosure_Arg4_Bind9(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4 +> +class FunctionExtClosure_Arg4_Bind10 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4); +public: + FunctionExtClosure_Arg4_Bind10(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10, arg1, arg2, arg3, arg4); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +template < + bool SelfDeleting, + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class FunctionExtClosure_Arg5_Bind0 : public ExtClosure { + typedef R (*FunctionType)(Arg1, Arg2, Arg3, Arg4, Arg5); +public: + FunctionExtClosure_Arg5_Bind0(FunctionType function): + m_function(function) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return m_function(arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class FunctionExtClosure_Arg5_Bind1 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5); +public: + FunctionExtClosure_Arg5_Bind1(FunctionType function, PreArg1 pa1): + m_function(function), m_pa1(pa1) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class FunctionExtClosure_Arg5_Bind2 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5); +public: + FunctionExtClosure_Arg5_Bind2(FunctionType function, PreArg1 pa1, PreArg2 pa2): + m_function(function), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class FunctionExtClosure_Arg5_Bind3 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5); +public: + FunctionExtClosure_Arg5_Bind3(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class FunctionExtClosure_Arg5_Bind4 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5); +public: + FunctionExtClosure_Arg5_Bind4(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class FunctionExtClosure_Arg5_Bind5 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5); +public: + FunctionExtClosure_Arg5_Bind5(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class FunctionExtClosure_Arg5_Bind6 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5); +public: + FunctionExtClosure_Arg5_Bind6(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class FunctionExtClosure_Arg5_Bind7 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5); +public: + FunctionExtClosure_Arg5_Bind7(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class FunctionExtClosure_Arg5_Bind8 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5); +public: + FunctionExtClosure_Arg5_Bind8(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class FunctionExtClosure_Arg5_Bind9 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5); +public: + FunctionExtClosure_Arg5_Bind9(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5 +> +class FunctionExtClosure_Arg5_Bind10 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5); +public: + FunctionExtClosure_Arg5_Bind10(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10, arg1, arg2, arg3, arg4, arg5); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +template < + bool SelfDeleting, + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class FunctionExtClosure_Arg6_Bind0 : public ExtClosure { + typedef R (*FunctionType)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + FunctionExtClosure_Arg6_Bind0(FunctionType function): + m_function(function) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return m_function(arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class FunctionExtClosure_Arg6_Bind1 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + FunctionExtClosure_Arg6_Bind1(FunctionType function, PreArg1 pa1): + m_function(function), m_pa1(pa1) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class FunctionExtClosure_Arg6_Bind2 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + FunctionExtClosure_Arg6_Bind2(FunctionType function, PreArg1 pa1, PreArg2 pa2): + m_function(function), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class FunctionExtClosure_Arg6_Bind3 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + FunctionExtClosure_Arg6_Bind3(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class FunctionExtClosure_Arg6_Bind4 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + FunctionExtClosure_Arg6_Bind4(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class FunctionExtClosure_Arg6_Bind5 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + FunctionExtClosure_Arg6_Bind5(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class FunctionExtClosure_Arg6_Bind6 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + FunctionExtClosure_Arg6_Bind6(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class FunctionExtClosure_Arg6_Bind7 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + FunctionExtClosure_Arg6_Bind7(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class FunctionExtClosure_Arg6_Bind8 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + FunctionExtClosure_Arg6_Bind8(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class FunctionExtClosure_Arg6_Bind9 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + FunctionExtClosure_Arg6_Bind9(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6 +> +class FunctionExtClosure_Arg6_Bind10 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); +public: + FunctionExtClosure_Arg6_Bind10(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10, arg1, arg2, arg3, arg4, arg5, arg6); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +template < + bool SelfDeleting, + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class FunctionExtClosure_Arg7_Bind0 : public ExtClosure { + typedef R (*FunctionType)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + FunctionExtClosure_Arg7_Bind0(FunctionType function): + m_function(function) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return m_function(arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class FunctionExtClosure_Arg7_Bind1 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + FunctionExtClosure_Arg7_Bind1(FunctionType function, PreArg1 pa1): + m_function(function), m_pa1(pa1) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class FunctionExtClosure_Arg7_Bind2 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + FunctionExtClosure_Arg7_Bind2(FunctionType function, PreArg1 pa1, PreArg2 pa2): + m_function(function), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class FunctionExtClosure_Arg7_Bind3 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + FunctionExtClosure_Arg7_Bind3(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class FunctionExtClosure_Arg7_Bind4 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + FunctionExtClosure_Arg7_Bind4(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class FunctionExtClosure_Arg7_Bind5 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + FunctionExtClosure_Arg7_Bind5(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class FunctionExtClosure_Arg7_Bind6 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + FunctionExtClosure_Arg7_Bind6(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class FunctionExtClosure_Arg7_Bind7 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + FunctionExtClosure_Arg7_Bind7(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class FunctionExtClosure_Arg7_Bind8 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + FunctionExtClosure_Arg7_Bind8(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class FunctionExtClosure_Arg7_Bind9 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + FunctionExtClosure_Arg7_Bind9(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7 +> +class FunctionExtClosure_Arg7_Bind10 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); +public: + FunctionExtClosure_Arg7_Bind10(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +template < + bool SelfDeleting, + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class FunctionExtClosure_Arg8_Bind0 : public ExtClosure { + typedef R (*FunctionType)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + FunctionExtClosure_Arg8_Bind0(FunctionType function): + m_function(function) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return m_function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class FunctionExtClosure_Arg8_Bind1 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + FunctionExtClosure_Arg8_Bind1(FunctionType function, PreArg1 pa1): + m_function(function), m_pa1(pa1) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class FunctionExtClosure_Arg8_Bind2 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + FunctionExtClosure_Arg8_Bind2(FunctionType function, PreArg1 pa1, PreArg2 pa2): + m_function(function), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class FunctionExtClosure_Arg8_Bind3 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + FunctionExtClosure_Arg8_Bind3(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class FunctionExtClosure_Arg8_Bind4 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + FunctionExtClosure_Arg8_Bind4(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class FunctionExtClosure_Arg8_Bind5 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + FunctionExtClosure_Arg8_Bind5(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class FunctionExtClosure_Arg8_Bind6 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + FunctionExtClosure_Arg8_Bind6(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class FunctionExtClosure_Arg8_Bind7 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + FunctionExtClosure_Arg8_Bind7(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class FunctionExtClosure_Arg8_Bind8 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + FunctionExtClosure_Arg8_Bind8(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class FunctionExtClosure_Arg8_Bind9 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + FunctionExtClosure_Arg8_Bind9(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8 +> +class FunctionExtClosure_Arg8_Bind10 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); +public: + FunctionExtClosure_Arg8_Bind10(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +template < + bool SelfDeleting, + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class FunctionExtClosure_Arg9_Bind0 : public ExtClosure { + typedef R (*FunctionType)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + FunctionExtClosure_Arg9_Bind0(FunctionType function): + m_function(function) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return m_function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class FunctionExtClosure_Arg9_Bind1 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + FunctionExtClosure_Arg9_Bind1(FunctionType function, PreArg1 pa1): + m_function(function), m_pa1(pa1) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class FunctionExtClosure_Arg9_Bind2 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + FunctionExtClosure_Arg9_Bind2(FunctionType function, PreArg1 pa1, PreArg2 pa2): + m_function(function), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class FunctionExtClosure_Arg9_Bind3 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + FunctionExtClosure_Arg9_Bind3(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class FunctionExtClosure_Arg9_Bind4 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + FunctionExtClosure_Arg9_Bind4(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class FunctionExtClosure_Arg9_Bind5 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + FunctionExtClosure_Arg9_Bind5(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class FunctionExtClosure_Arg9_Bind6 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + FunctionExtClosure_Arg9_Bind6(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class FunctionExtClosure_Arg9_Bind7 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + FunctionExtClosure_Arg9_Bind7(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class FunctionExtClosure_Arg9_Bind8 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + FunctionExtClosure_Arg9_Bind8(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class FunctionExtClosure_Arg9_Bind9 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + FunctionExtClosure_Arg9_Bind9(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9 +> +class FunctionExtClosure_Arg9_Bind10 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); +public: + FunctionExtClosure_Arg9_Bind10(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +template < + bool SelfDeleting, + typename R, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class FunctionExtClosure_Arg10_Bind0 : public ExtClosure { + typedef R (*FunctionType)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + FunctionExtClosure_Arg10_Bind0(FunctionType function): + m_function(function) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return m_function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class FunctionExtClosure_Arg10_Bind1 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + FunctionExtClosure_Arg10_Bind1(FunctionType function, PreArg1 pa1): + m_function(function), m_pa1(pa1) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class FunctionExtClosure_Arg10_Bind2 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + FunctionExtClosure_Arg10_Bind2(FunctionType function, PreArg1 pa1, PreArg2 pa2): + m_function(function), m_pa1(pa1), m_pa2(pa2) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class FunctionExtClosure_Arg10_Bind3 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + FunctionExtClosure_Arg10_Bind3(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class FunctionExtClosure_Arg10_Bind4 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + FunctionExtClosure_Arg10_Bind4(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class FunctionExtClosure_Arg10_Bind5 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + FunctionExtClosure_Arg10_Bind5(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class FunctionExtClosure_Arg10_Bind6 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + FunctionExtClosure_Arg10_Bind6(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class FunctionExtClosure_Arg10_Bind7 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + FunctionExtClosure_Arg10_Bind7(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class FunctionExtClosure_Arg10_Bind8 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + FunctionExtClosure_Arg10_Bind8(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class FunctionExtClosure_Arg10_Bind9 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + FunctionExtClosure_Arg10_Bind9(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; +}; + +template < + bool SelfDeleting, + typename R, + typename PreArg1, + typename PreArg2, + typename PreArg3, + typename PreArg4, + typename PreArg5, + typename PreArg6, + typename PreArg7, + typename PreArg8, + typename PreArg9, + typename PreArg10, + typename Arg1, + typename Arg2, + typename Arg3, + typename Arg4, + typename Arg5, + typename Arg6, + typename Arg7, + typename Arg8, + typename Arg9, + typename Arg10 +> +class FunctionExtClosure_Arg10_Bind10 : public ExtClosure { + typedef R (*FunctionType)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10); +public: + FunctionExtClosure_Arg10_Bind10(FunctionType function, PreArg1 pa1, PreArg2 pa2, PreArg3 pa3, PreArg4 pa4, PreArg5 pa5, PreArg6 pa6, PreArg7 pa7, PreArg8 pa8, PreArg9 pa9, PreArg10 pa10): + m_function(function), m_pa1(pa1), m_pa2(pa2), m_pa3(pa3), m_pa4(pa4), m_pa5(pa5), m_pa6(pa6), m_pa7(pa7), m_pa8(pa8), m_pa9(pa9), m_pa10(pa10) {} + virtual R Run(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9, Arg10 arg10) { + ConditionalAutoDeleter self_deleter(this); + return m_function(m_pa1, m_pa2, m_pa3, m_pa4, m_pa5, m_pa6, m_pa7, m_pa8, m_pa9, m_pa10, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + virtual bool IsSelfDelete() const { return SelfDeleting; } +private: + FunctionType m_function; + typename ParamTraits::StorageType m_pa1; + typename ParamTraits::StorageType m_pa2; + typename ParamTraits::StorageType m_pa3; + typename ParamTraits::StorageType m_pa4; + typename ParamTraits::StorageType m_pa5; + typename ParamTraits::StorageType m_pa6; + typename ParamTraits::StorageType m_pa7; + typename ParamTraits::StorageType m_pa8; + typename ParamTraits::StorageType m_pa9; + typename ParamTraits::StorageType m_pa10; +}; + +//////////////////////////////////////////////////// +//////// ExtClosure create helper functions ///////////// +//////////////////////////////////////////////////// +//////////// for class method //////////////////////// + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)()) { + return new MethodExtClosure_Arg0_Bind0(object, method); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg0_Bind1(object, method, pa1); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg0_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg0_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg0_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg0_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg0_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg0_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg0_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg0_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg0_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(Arg1)) { + return new MethodExtClosure_Arg1_Bind0(object, method); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, Arg1) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg1_Bind1(object, method, pa1); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg1_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg1_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg1_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg1_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg1_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg1_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg1_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg1_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg1_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(Arg1, Arg2)) { + return new MethodExtClosure_Arg2_Bind0(object, method); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg2_Bind1(object, method, pa1); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg2_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg2_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg2_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg2_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg2_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg2_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg2_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg2_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg2_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(Arg1, Arg2, Arg3)) { + return new MethodExtClosure_Arg3_Bind0(object, method); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg3_Bind1(object, method, pa1); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg3_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg3_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg3_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg3_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg3_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg3_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg3_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg3_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg3_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(Arg1, Arg2, Arg3, Arg4)) { + return new MethodExtClosure_Arg4_Bind0(object, method); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg4_Bind1(object, method, pa1); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg4_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg4_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg4_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg4_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg4_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg4_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg4_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg4_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg4_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(Arg1, Arg2, Arg3, Arg4, Arg5)) { + return new MethodExtClosure_Arg5_Bind0(object, method); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg5_Bind1(object, method, pa1); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg5_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg5_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg5_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg5_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg5_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg5_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg5_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg5_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg5_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)) { + return new MethodExtClosure_Arg6_Bind0(object, method); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg6_Bind1(object, method, pa1); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg6_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg6_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg6_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg6_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg6_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg6_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg6_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg6_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg6_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)) { + return new MethodExtClosure_Arg7_Bind0(object, method); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg7_Bind1(object, method, pa1); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg7_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg7_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg7_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg7_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg7_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg7_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg7_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg7_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg7_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)) { + return new MethodExtClosure_Arg8_Bind0(object, method); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg8_Bind1(object, method, pa1); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg8_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg8_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg8_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg8_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg8_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg8_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg8_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg8_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg8_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9)) { + return new MethodExtClosure_Arg9_Bind0(object, method); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg9_Bind1(object, method, pa1); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg9_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg9_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg9_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg9_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg9_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg9_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg9_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg9_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg9_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10)) { + return new MethodExtClosure_Arg10_Bind0(object, method); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg10_Bind1(object, method, pa1); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg10_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg10_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg10_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg10_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg10_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg10_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg10_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg10_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg10_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +//////////////////////////////////////////////////// +//////// ExtClosure create helper functions ///////////// +//////////////////////////////////////////////////// +//////////// for class method //////////////////////// + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)()) { + return new MethodExtClosure_Arg0_Bind0(object, method); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg0_Bind1(object, method, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg0_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg0_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg0_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg0_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg0_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg0_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg0_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg0_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg0_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(Arg1)) { + return new MethodExtClosure_Arg1_Bind0(object, method); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, Arg1) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg1_Bind1(object, method, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg1_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg1_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg1_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg1_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg1_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg1_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg1_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg1_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg1_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(Arg1, Arg2)) { + return new MethodExtClosure_Arg2_Bind0(object, method); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg2_Bind1(object, method, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg2_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg2_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg2_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg2_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg2_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg2_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg2_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg2_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg2_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(Arg1, Arg2, Arg3)) { + return new MethodExtClosure_Arg3_Bind0(object, method); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg3_Bind1(object, method, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg3_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg3_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg3_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg3_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg3_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg3_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg3_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg3_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg3_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(Arg1, Arg2, Arg3, Arg4)) { + return new MethodExtClosure_Arg4_Bind0(object, method); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg4_Bind1(object, method, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg4_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg4_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg4_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg4_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg4_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg4_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg4_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg4_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg4_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(Arg1, Arg2, Arg3, Arg4, Arg5)) { + return new MethodExtClosure_Arg5_Bind0(object, method); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg5_Bind1(object, method, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg5_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg5_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg5_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg5_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg5_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg5_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg5_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg5_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg5_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)) { + return new MethodExtClosure_Arg6_Bind0(object, method); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg6_Bind1(object, method, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg6_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg6_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg6_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg6_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg6_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg6_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg6_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg6_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg6_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)) { + return new MethodExtClosure_Arg7_Bind0(object, method); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg7_Bind1(object, method, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg7_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg7_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg7_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg7_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg7_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg7_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg7_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg7_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg7_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)) { + return new MethodExtClosure_Arg8_Bind0(object, method); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg8_Bind1(object, method, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg8_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg8_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg8_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg8_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg8_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg8_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg8_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg8_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg8_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9)) { + return new MethodExtClosure_Arg9_Bind0(object, method); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg9_Bind1(object, method, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg9_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg9_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg9_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg9_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg9_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg9_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg9_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg9_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg9_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10)) { + return new MethodExtClosure_Arg10_Bind0(object, method); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1) { + return new MethodExtClosure_Arg10_Bind1(object, method, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new MethodExtClosure_Arg10_Bind2(object, method, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new MethodExtClosure_Arg10_Bind3(object, method, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new MethodExtClosure_Arg10_Bind4(object, method, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new MethodExtClosure_Arg10_Bind5(object, method, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new MethodExtClosure_Arg10_Bind6(object, method, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new MethodExtClosure_Arg10_Bind7(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new MethodExtClosure_Arg10_Bind8(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new MethodExtClosure_Arg10_Bind9(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(ClassPointer object, R (MethodClass::*method)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new MethodExtClosure_Arg10_Bind10(object, method, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +//////////////////////////////////////////////////// +//////// ExtClosure create helper functions ///////////// +//////////////////////////////////////////////////// +//////////// for nomal function //////////////////////// + +template +ExtClosure* NewExtClosure(R (*function)()) { + return new FunctionExtClosure_Arg0_Bind0(function); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg0_Bind1(function, pa1); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg0_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg0_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg0_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg0_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg0_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg0_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg0_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg0_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg0_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewExtClosure(R (*function)(Arg1)) { + return new FunctionExtClosure_Arg1_Bind0(function); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, Arg1) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg1_Bind1(function, pa1); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg1_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg1_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg1_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg1_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg1_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg1_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg1_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg1_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg1_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewExtClosure(R (*function)(Arg1, Arg2)) { + return new FunctionExtClosure_Arg2_Bind0(function); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg2_Bind1(function, pa1); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg2_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg2_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg2_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg2_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg2_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg2_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg2_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg2_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg2_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewExtClosure(R (*function)(Arg1, Arg2, Arg3)) { + return new FunctionExtClosure_Arg3_Bind0(function); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg3_Bind1(function, pa1); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg3_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg3_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg3_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg3_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg3_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg3_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg3_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg3_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg3_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewExtClosure(R (*function)(Arg1, Arg2, Arg3, Arg4)) { + return new FunctionExtClosure_Arg4_Bind0(function); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg4_Bind1(function, pa1); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg4_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg4_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg4_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg4_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg4_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg4_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg4_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg4_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg4_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewExtClosure(R (*function)(Arg1, Arg2, Arg3, Arg4, Arg5)) { + return new FunctionExtClosure_Arg5_Bind0(function); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg5_Bind1(function, pa1); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg5_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg5_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg5_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg5_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg5_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg5_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg5_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg5_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg5_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewExtClosure(R (*function)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)) { + return new FunctionExtClosure_Arg6_Bind0(function); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg6_Bind1(function, pa1); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg6_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg6_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg6_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg6_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg6_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg6_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg6_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg6_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg6_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewExtClosure(R (*function)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)) { + return new FunctionExtClosure_Arg7_Bind0(function); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg7_Bind1(function, pa1); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg7_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg7_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg7_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg7_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg7_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg7_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg7_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg7_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg7_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewExtClosure(R (*function)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)) { + return new FunctionExtClosure_Arg8_Bind0(function); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg8_Bind1(function, pa1); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg8_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg8_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg8_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg8_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg8_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg8_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg8_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg8_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg8_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewExtClosure(R (*function)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9)) { + return new FunctionExtClosure_Arg9_Bind0(function); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg9_Bind1(function, pa1); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg9_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg9_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg9_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg9_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg9_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg9_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg9_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg9_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg9_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewExtClosure(R (*function)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10)) { + return new FunctionExtClosure_Arg10_Bind0(function); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg10_Bind1(function, pa1); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg10_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg10_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg10_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg10_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg10_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg10_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg10_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg10_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg10_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +//////////////////////////////////////////////////// +//////// ExtClosure create helper functions ///////////// +//////////////////////////////////////////////////// +//////////// for nomal function //////////////////////// + +template +ExtClosure* NewPermanentExtClosure(R (*function)()) { + return new FunctionExtClosure_Arg0_Bind0(function); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg0_Bind1(function, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg0_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg0_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg0_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg0_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg0_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg0_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg0_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg0_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg0_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(Arg1)) { + return new FunctionExtClosure_Arg1_Bind0(function); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, Arg1) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg1_Bind1(function, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg1_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg1_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg1_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg1_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg1_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg1_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg1_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg1_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg1_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(Arg1, Arg2)) { + return new FunctionExtClosure_Arg2_Bind0(function); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg2_Bind1(function, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg2_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg2_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg2_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg2_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg2_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg2_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg2_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg2_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg2_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(Arg1, Arg2, Arg3)) { + return new FunctionExtClosure_Arg3_Bind0(function); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg3_Bind1(function, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg3_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg3_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg3_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg3_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg3_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg3_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg3_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg3_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg3_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(Arg1, Arg2, Arg3, Arg4)) { + return new FunctionExtClosure_Arg4_Bind0(function); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg4_Bind1(function, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg4_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg4_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg4_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg4_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg4_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg4_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg4_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg4_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg4_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(Arg1, Arg2, Arg3, Arg4, Arg5)) { + return new FunctionExtClosure_Arg5_Bind0(function); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg5_Bind1(function, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg5_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg5_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg5_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg5_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg5_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg5_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg5_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg5_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg5_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)) { + return new FunctionExtClosure_Arg6_Bind0(function); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg6_Bind1(function, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg6_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg6_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg6_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg6_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg6_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg6_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg6_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg6_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg6_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)) { + return new FunctionExtClosure_Arg7_Bind0(function); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg7_Bind1(function, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg7_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg7_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg7_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg7_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg7_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg7_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg7_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg7_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg7_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)) { + return new FunctionExtClosure_Arg8_Bind0(function); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg8_Bind1(function, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg8_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg8_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg8_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg8_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg8_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg8_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg8_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg8_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg8_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9)) { + return new FunctionExtClosure_Arg9_Bind0(function); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg9_Bind1(function, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg9_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg9_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg9_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg9_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg9_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg9_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg9_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg9_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg9_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10)) { + return new FunctionExtClosure_Arg10_Bind0(function); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1) { + return new FunctionExtClosure_Arg10_Bind1(function, pa1); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2) { + return new FunctionExtClosure_Arg10_Bind2(function, pa1, pa2); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3) { + return new FunctionExtClosure_Arg10_Bind3(function, pa1, pa2, pa3); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4) { + return new FunctionExtClosure_Arg10_Bind4(function, pa1, pa2, pa3, pa4); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5) { + return new FunctionExtClosure_Arg10_Bind5(function, pa1, pa2, pa3, pa4, pa5); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6) { + return new FunctionExtClosure_Arg10_Bind6(function, pa1, pa2, pa3, pa4, pa5, pa6); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7) { + return new FunctionExtClosure_Arg10_Bind7(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8) { + return new FunctionExtClosure_Arg10_Bind8(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9) { + return new FunctionExtClosure_Arg10_Bind9(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9); +} + +template +ExtClosure* NewPermanentExtClosure(R (*function)(PreArg1, PreArg2, PreArg3, PreArg4, PreArg5, PreArg6, PreArg7, PreArg8, PreArg9, PreArg10, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) + , typename ParamTraits::ForwardType pa1 + , typename ParamTraits::ForwardType pa2 + , typename ParamTraits::ForwardType pa3 + , typename ParamTraits::ForwardType pa4 + , typename ParamTraits::ForwardType pa5 + , typename ParamTraits::ForwardType pa6 + , typename ParamTraits::ForwardType pa7 + , typename ParamTraits::ForwardType pa8 + , typename ParamTraits::ForwardType pa9 + , typename ParamTraits::ForwardType pa10) { + return new FunctionExtClosure_Arg10_Bind10(function, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10); +} + +} // namespace pbrpc + +} // namespace sofa + +#endif // _SOFA_PBRPC_EXT_CLOSURE_H_ diff --git a/src/sofa/pbrpc/ext_closure_gen.pl b/src/sofa/pbrpc/ext_closure_gen.pl new file mode 100644 index 0000000..907d046 --- /dev/null +++ b/src/sofa/pbrpc/ext_closure_gen.pl @@ -0,0 +1,470 @@ +#!/usr/bin/perl -w + +use strict; +use warnings; + +#this perl script is used to generate ExtClosure + +my $kPreMaxArgs = 10; +my $kMaxArgs = 10; + +sub PrintHead() +{ + print "#ifndef _SOFA_PBRPC_EXT_CLOSURE_H_\n"; + print "#define _SOFA_PBRPC_EXT_CLOSURE_H_\n\n"; + + print "/////////////////////////////////////////////////////\n"; + print "// DO NOT EDIT!!!\n"; + print "// this header file is auto generated by perl script\n"; + print "// edit the generator if necessary\n"; + print "/////////////////////////////////////////////////////\n\n"; + + print "/////////////////////////////////////////////////////\n"; + print "// Support:\n"; + print "// 1, Support pre-bind and post-bind for general\n"; + print "// function and class method, up to 10 arguments.\n"; + print "// 2, Support pass argument by reference, though bind\n"; + print "// always by value.\n"; + print "// 3, When bind class method, support use\n"; + print "// \"sofa::pbrpc::shared_ptr\" as this pointer of class.\n"; + print "// 4, Support create temporary and permanent closure:\n"; + print "// Temporary closure (self destoryed after call):\n"; + print "// NewExtClosure();\n"; + print "// Permanent closure (do not destoryed by self):\n"; + print "// NewPermanentExtClosure();\n"; + print "/////////////////////////////////////////////////////\n\n"; + + print "/////////////////////////////////////////////////////\n"; + print "// Usage:\n"; + print "// 1, General function:\n"; + print "// \n"; + print "// void f1(int pre_arg, double post_arg);\n"; + print "// \n"; + print "// ExtClosure* c1 = NewExtClosure(&f1, 1);\n"; + print "// c1->Run(2.0);\n"; + print "// \n"; + print "// ExtClosure* c2 = NewPermanentExtClosure(&f1, 1);\n"; + print "// c2->Run(2.0);\n"; + print "// \n"; + print "// 2, Class method:\n"; + print "// \n"; + print "// class C1\n"; + print "// {\n"; + print "// public:\n"; + print "// int m1(int pre_arg, double post_arg);\n"; + print "// };\n"; + print "// \n"; + print "// C1 obj;\n"; + print "// \n"; + print "// ExtClosure* c3 = NewExtClosure(&obj, &C1::m1, 1);\n"; + print "// c3->Run(2.0);\n"; + print "// \n"; + print "// ExtClosure* c4 = NewPermanentExtClosure(&obj, &C1::m1, 1);\n"; + print "// c4->Run(2.0);\n"; + print "// \n"; + print "// class C2 : public sofa::pbrpc::enable_shared_from_this\n"; + print "// {\n"; + print "// public:\n"; + print "// int m1(int pre_arg, double post_arg);\n"; + print "// \n"; + print "// void m2()\n"; + print "// {\n"; + print "// ExtClosure* c7 = NewExtClosure(\n"; + print "// shared_from_this(), &C2::m1, 1);\n"; + print "// c7->Run(2.0);\n"; + print "// \n"; + print "// ExtClosure* c8 = NewPermanentExtClosure(\n"; + print "// shared_from_this(), &C2::m1, 1);\n"; + print "// c8->Run(2.0);\n"; + print "// }\n"; + print "// };\n"; + print "// \n"; + print "/////////////////////////////////////////////////////\n\n"; + + print "/////////////////////////////////////////////////////\n"; + print "//\n"; + print "// //////// ExtClosure without return type ////////\n"; + for (my $i = 0; $i <= $kMaxArgs; $i++) + { + print "// ExtClosure: x->Run("; + for (my $j = 1; $j <= $i; ++$j) + { + print "arg$j"; + print ", " if ($j < $i); + } + + print "), ExtClosure can pre-bind 0~${kPreMaxArgs} argument(s).\n"; + } + print "//\n"; + print "// /////// ExtClosure with return type of R ///////\n"; + for (my $i = 0; $i <= $kMaxArgs; $i++) + { + print "// ExtClosure: R = x->Run("; + for (my $j = 1; $j <= $i; ++$j) + { + print "arg$j"; + print ", " if ($j < $i); + } + print "), ExtClosure can pre-bind 0~${kPreMaxArgs} argument(s).\n"; + } + print "//\n"; + print "/////////////////////////////////////////////////////\n\n"; + + print "#include \n\n"; + + print "namespace sofa {\n"; + print "namespace pbrpc{\n"; +} + +sub PrintEnd +{ + print "} // namespace pbrpc\n\n"; + print "} // namespace sofa\n\n"; + + print "#endif // _SOFA_PBRPC_EXT_CLOSURE_H_\n"; +} + +sub PrintExtClosureBase() +{ + print " +/// base class for all ExtClosures +class ExtClosureBase +{ +public: + virtual ~ExtClosureBase() {} + virtual bool IsSelfDelete() const = 0; +}; + +"; +} + +sub PrintExtClosure() +{ + my $kTotalArgs = $kPreMaxArgs + $kMaxArgs; + print "// primary template\n"; + print "template "; + print "class ExtClosure : public ExtClosureBase\n"; + print "{\n"; + print "};\n"; + + for (my $i = 0; $i < $kTotalArgs; $i++) + { + if ($i <= 1) + { + print "\n// specified for $i argument\n"; + } + else + { + print "\n// specified for $i arguments\n"; + } + + print "template <\n typename R"; + + my ($j); + for ($j = 1; $j <= $i; ++$j) + { + print ",\n typename Arg$j"; + } + + print "\n>\n"; + print "class ExtClosure 1; + print "Arg$j"; + } + + print ")>\n : public ExtClosureBase\n{\npublic:\n"; + print " virtual R Run("; + + for ($j = 1; $j <= $i; ++$j) + { + print "Arg$j arg$j"; + + if ($j != $i) + { + print ", "; + } + } + + print ") = 0;\n"; + print "};\n"; + } +} + +sub PrintExtClosure_Arg_Bind($$$) +{ + my ($type, $num_pre_args, $num_args) = @_; + my $k; + + # print template argument list + print "template <\n bool SelfDeleting,\n typename R"; + print ",\n typename ClassPointer, typename MethodClass" if ($type eq "Method"); + for ($k = 1; $k <= $num_pre_args; $k++) + { + print ",\n typename PreArg$k"; + } + for ($k = 1; $k <= $num_args; $k++) + { + print ",\n typename Arg$k"; + } + print "\n>\n"; + + # print class definition + my $ClassName = "${type}ExtClosure_Arg${num_args}_Bind${num_pre_args}"; + print "class ${ClassName} : public ExtClosure 1; + print "Arg$k"; + } + print ")> {\n"; + + # print typedef + print " typedef R ("; + print "MethodClass::" if ($type eq "Method"); + print "*${type}Type)("; + + for ($k = 1; $k <= $num_pre_args; $k++) + { + print "PreArg$k"; + print ", " if ($k < $num_pre_args || $num_args > 0); + } + + for ($k = 1; $k <= $num_args; $k++) + { + print "Arg$k"; + print ", " if ($k < $num_args); + } + + print ");\n"; + + print "public:\n"; + + # print ctor + print " $ClassName("; + + if ($type eq "Method") + { + print "ClassPointer object, MethodType method"; + } + elsif ($type eq "Function") + { + print "FunctionType function"; + } + + for ($k = 1; $k <= $num_pre_args; $k++) + { + print ", PreArg$k pa$k"; + } + print "):\n "; + + if ($type eq "Method") + { + print "m_object(object), m_method(method)"; + } + elsif ($type eq "Function") + { + print "m_function(function)"; + } + + for ($k = 1; $k <= $num_pre_args; $k++) + { + print ", m_pa${k}(pa${k})"; + } + print " {}\n"; + + # print the `Run' function + print " virtual R Run("; + for ($k = 1; $k <= $num_args; $k++) + { + print "Arg${k} arg${k}"; + print ", " if ($k < $num_args); + } + print ") {\n"; + print " ConditionalAutoDeleter self_deleter(this);\n"; + print " return "; + if ($type eq "Method") + { + print "(get_pointer(m_object)->*m_method)("; + } + elsif ($type eq "Function") + { + print "m_function("; + } + for ($k = 1; $k <= $num_pre_args; $k++) + { + print "m_pa$k"; + print ", " if $k != $num_pre_args || $num_args > 0; + } + for ($k = 1; $k <= $num_args; $k++) + { + print "arg$k"; + print ", " if $k != $num_args; + } + print ");\n"; + print " }\n"; + + # IsSelfDelete + print " virtual bool IsSelfDelete() const { return SelfDeleting; }\n"; + + # member variables + print "private:\n"; + if ($type eq "Method") + { + print " ClassPointer m_object;\n MethodType m_method;\n"; + } + if ($type eq "Function") + { + print " FunctionType m_function;\n"; + } + for ($k = 1; $k <= $num_pre_args; $k++) + { + print " typename ParamTraits::StorageType m_pa${k};\n"; + } + print "};\n\n"; +} + +sub PrintAllExtClosure_Arg_Binds($) +{ + my ($type) = @_; + print "////////////////////////////////////////////////////\n"; + + if ($type eq "Method") + { + print "//////////// class method closures /////////////////\n"; + } + else + { + print "//////////// nomal function closures //////////////////\n"; + } + print "////////////////////////////////////////////////////\n\n"; + + for (my $num_args = 0; $num_args <= $kMaxArgs; ++$num_args) + { + for (my $num_pre_args = 0; $num_pre_args <= $kPreMaxArgs; $num_pre_args++) + { + PrintExtClosure_Arg_Bind($type, $num_pre_args, $num_args); + } + } +} + +sub PrintNewExtClosure($$) +{ + my ($type, $self_deleting) = @_; + print "////////////////////////////////////////////////////\n"; + print "//////// ExtClosure create helper functions /////////////\n"; + print "////////////////////////////////////////////////////\n"; + if ($type eq "Method") + { + print "//////////// for class method ////////////////////////\n\n"; + } + else + { + print "//////////// for nomal function ////////////////////////\n\n"; + } + + # $resultType = $has_result ? "R" : "void"; + for (my $num_args = 0; $num_args <= $kMaxArgs; $num_args++) + { + for (my $num_pre_args = 0; $num_pre_args <= $kPreMaxArgs; $num_pre_args++) + { + my $k; + print "template \n"; + print "ExtClosure 1; + print "Arg$k"; + } + print ")>* "; + if ($self_deleting eq "false") + { + print "NewPermanentExtClosure("; + } + else + { + print "NewExtClosure("; + } + if ($type eq "Method") + { + print "ClassPointer object, R (MethodClass::*method)("; + } + else + { + print "R (*function)("; + } + for ($k = 1; $k <= $num_pre_args; $k++) + { + print "PreArg$k"; + print ", " if ($k < $num_pre_args || $num_args > 0); + } + for ($k = 1; $k <= $num_args; $k++) + { + print "Arg$k"; + print ", " if ($k < $num_args); + } + print ")"; + for ($k = 1; $k <= $num_pre_args; $k++) + { + print "\n , typename ParamTraits::ForwardType pa$k"; + } + print ") {\n"; + + if ($type eq "Method") + { + print " return new MethodExtClosure_Arg${num_args}_Bind${num_pre_args}<$self_deleting, R, ClassPointer, MethodClass"; + } + else + { + print " return new FunctionExtClosure_Arg${num_args}_Bind${num_pre_args}<$self_deleting, R"; + } + for ($k = 1; $k <= $num_pre_args; $k++) + { + print ", PreArg$k"; + } + for ($k = 1; $k <= $num_args; $k++) + { + print ", Arg$k"; + } + print ">("; + if ($type eq "Method") + { + print "object, method"; + } + else + { + print "function"; + } + for ($k = 1; $k <= $num_pre_args; $k++) + { + print ", pa$k"; + } + print ");\n}\n\n"; + } + } +} + +# Start real work +PrintHead(); +PrintExtClosureBase(); +PrintExtClosure(); +PrintAllExtClosure_Arg_Binds("Method"); +PrintAllExtClosure_Arg_Binds("Function"); +PrintNewExtClosure("Method", "true"); +PrintNewExtClosure("Method", "false"); +PrintNewExtClosure("Function", "true"); +PrintNewExtClosure("Function", "false"); +PrintEnd(); + diff --git a/src/sofa/pbrpc/fast_lock.h b/src/sofa/pbrpc/fast_lock.h new file mode 100644 index 0000000..458ffe5 --- /dev/null +++ b/src/sofa/pbrpc/fast_lock.h @@ -0,0 +1,27 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_FAST_LOCK_H_ +#define _SOFA_PBRPC_FAST_LOCK_H_ + +#include +#include + +namespace sofa { +namespace pbrpc { + +#if defined( SOFA_PBRPC_USE_SPINLOCK ) + typedef SpinLock FastLock; +#else + typedef MutexLock FastLock; +#endif // defined( SOFA_PBRPC_USE_SPINLOCK ) + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_FAST_LOCK_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/flow_controller.h b/src/sofa/pbrpc/flow_controller.h new file mode 100644 index 0000000..3494f0a --- /dev/null +++ b/src/sofa/pbrpc/flow_controller.h @@ -0,0 +1,103 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_FLOW_CONTROLLER_H_ +#define _SOFA_PBRPC_FLOW_CONTROLLER_H_ + +#include + +namespace sofa { +namespace pbrpc { + +class FlowController +{ +public: + FlowController(bool read_no_limit, int read_quota, + bool write_no_limit, int write_quota) + : _read_no_limit(read_no_limit), _read_quota(read_quota) + , _write_no_limit(write_no_limit), _write_quota(write_quota) {} + + ~FlowController() {} + + // Reset read quota. + // @param read_no_limit if set as no limit. + // @param quota the new quota, only useful when read_no_limit is false. + void reset_read_quota(bool read_no_limit, int quota) + { + _read_no_limit = read_no_limit; + _read_quota = quota; + } + + // Reset read quota. + // @param quota the new quota. + void reset_read_quota(int quota) + { + _read_quota = quota; + } + + // Reset write quota. + // @param write_no_limit if set as no limit. + // @param quota the new quota, only useful when write_no_limit is false. + void reset_write_quota(bool write_no_limit, int quota) + { + _write_no_limit = write_no_limit; + _write_quota = quota; + } + + // Reset write quota. + // @param quota the new quota. + void reset_write_quota(int quota) + { + _write_quota = quota; + } + + // Check if has more read quota. + bool has_read_quota() const + { + return _read_no_limit || _read_quota > 0; + } + + // Check if has more write quota. + bool has_write_quota() const + { + return _write_no_limit || _write_quota > 0; + } + + // Acquire some read quota. + // @param quota the quota expect to acquire. + // @return >0 if acquire succeed. + // @return <=0 if acquire failed, and the return value can be used as sequence number + // to sort trigger order: closer to zero, earlier to trigger. + int acquire_read_quota(int quota) + { + return _read_no_limit ? 1 : atomic_add_ret_old(&_read_quota, -quota); + } + + // Acquire some write quota. + // @param quota the quota expect to acquire. + // @return >0 if acquire succeed. + // @return <=0 if acquire failed, and the return value can be used as sequence number + // to sort trigger order: closer to zero, earlier to trigger. + int acquire_write_quota(int quota) + { + return _write_no_limit ? 1 : atomic_add_ret_old(&_write_quota, -quota); + } + +private: + bool _read_no_limit; + volatile int _read_quota; + bool _write_no_limit; + volatile int _write_quota; + + SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(FlowController); +}; // class FlowController + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_FLOW_CONTROLLER_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/func_tracer.h b/src/sofa/pbrpc/func_tracer.h new file mode 100644 index 0000000..9172636 --- /dev/null +++ b/src/sofa/pbrpc/func_tracer.h @@ -0,0 +1,62 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_FUNC_TRACER_H_ +#define _SOFA_PBRPC_FUNC_TRACER_H_ + +#include + +#include + +namespace sofa { +namespace pbrpc { +namespace internal { + +class FuncTracer +{ +public: + FuncTracer(const char* file, size_t line, const char* func) + : _file(file) + , _line(line) + , _func(func) + { +#if defined( LOG ) + LOG(INFO) << _file << ": " << _line << ": >" << _func << "()"; +#else + SLOG(TRACE, "%s: %u: >%s()", _file, _line, _func); +#endif + } + + ~FuncTracer() + { +#if defined( LOG ) + LOG(INFO) << _file << ": " << _line << ": <" << _func << "()"; +#else + SLOG(TRACE, "%s: %u: <%s()", _file, _line, _func); +#endif + } + +private: + const char* _file; + size_t _line; + const char* _func; +}; // class Tracer + +} // namespace internal +} // namespace pbrpc +} // namespace sofa + +#if defined( SOFA_PBRPC_ENABLE_FUNCTION_TRACE ) +# define SOFA_PBRPC_FUNCTION_TRACE \ + ::sofa::pbrpc::internal::FuncTracer __sofa_function_tracer__( \ + __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) +#else +# define SOFA_PBRPC_FUNCTION_TRACE +#endif // defined( SOFA_PBRPC_ENABLE_FUNCTION_TRACE ) + +#endif // _SOFA_PBRPC_FUNC_TRACER_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/gzip_stream.cc b/src/sofa/pbrpc/gzip_stream.cc new file mode 100644 index 0000000..e00a557 --- /dev/null +++ b/src/sofa/pbrpc/gzip_stream.cc @@ -0,0 +1,380 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from Protocal Buffers. +// +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: brianolson@google.com (Brian Olson) +// +// This file contains the implementation of classes GzipInputStream and +// GzipOutputStream. + +//#include + +#include + +#include + +namespace sofa { +namespace pbrpc { + +static const int kDefaultBufferSize = 65536; + +GzipInputStream::GzipInputStream( + ZeroCopyInputStream* sub_stream, Format format, int buffer_size) + : format_(format), sub_stream_(sub_stream), zerror_(Z_OK) { + zcontext_.next_in = NULL; + zcontext_.avail_in = 0; + zcontext_.total_in = 0; + zcontext_.next_out = NULL; + zcontext_.avail_out = 0; + zcontext_.total_out = 0; + zcontext_.msg = NULL; + zcontext_.state = NULL; + zcontext_.zalloc = Z_NULL; + zcontext_.zfree = Z_NULL; + zcontext_.opaque = Z_NULL; + zcontext_.total_out = 0; + zcontext_.data_type = Z_BINARY; + zcontext_.adler = 0; + zcontext_.reserved = 0; + if (buffer_size == -1) { + output_buffer_length_ = kDefaultBufferSize; + } else { + output_buffer_length_ = buffer_size; + } + output_buffer_ = operator new(output_buffer_length_); + GOOGLE_CHECK(output_buffer_ != NULL); + zcontext_.next_out = static_cast(output_buffer_); + zcontext_.avail_out = output_buffer_length_; + output_position_ = output_buffer_; +} + +GzipInputStream::~GzipInputStream() { + operator delete(output_buffer_); + // Back up input stream if there are unused bytes + if (ExpectAtEnd() && zcontext_.avail_in > 0) { + sub_stream_->BackUp(zcontext_.avail_in); + zcontext_.avail_in = 0; + } + zerror_ = inflateEnd(&zcontext_); +} + +static inline int internalInflateInit2( + z_stream* zcontext, GzipInputStream::Format format) { + int windowBitsFormat = 0; + switch (format) { + case GzipInputStream::GZIP: windowBitsFormat = 16; break; + case GzipInputStream::AUTO: windowBitsFormat = 32; break; + case GzipInputStream::ZLIB: windowBitsFormat = 0; break; + } + return inflateInit2(zcontext, /* windowBits */15 | windowBitsFormat); +} + +int GzipInputStream::Inflate(int flush) { + if ((zerror_ == Z_OK) && (zcontext_.avail_out == 0)) { + // previous inflate filled output buffer. don't change input params yet. + } else if (zcontext_.avail_in == 0) { + const void* in; + int in_size; + bool first = zcontext_.next_in == NULL; + bool ok = sub_stream_->Next(&in, &in_size); + if (!ok) { + zcontext_.next_out = NULL; + zcontext_.avail_out = 0; + return Z_STREAM_END; + } + zcontext_.next_in = static_cast(const_cast(in)); + + zcontext_.avail_in = in_size; + if (first) { + int error = internalInflateInit2(&zcontext_, format_); + if (error != Z_OK) { + return error; + } + } + } + zcontext_.next_out = static_cast(output_buffer_); + zcontext_.avail_out = output_buffer_length_; + output_position_ = output_buffer_; + int error = inflate(&zcontext_, flush); + return error; +} + +void GzipInputStream::DoNextOutput(const void** data, int* size) { + *data = output_position_; + *size = ((uintptr_t)zcontext_.next_out) - ((uintptr_t)output_position_); + output_position_ = zcontext_.next_out; +} + +// implements ZeroCopyInputStream ---------------------------------- +bool GzipInputStream::Next(const void** data, int* size) { + bool ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END) + || (zerror_ == Z_BUF_ERROR); + if ((!ok) || (zcontext_.next_out == NULL)) { + return false; + } + if (zcontext_.next_out != output_position_) { + DoNextOutput(data, size); + return true; + } + if (zerror_ == Z_STREAM_END) { + // First backup stream + if (zcontext_.avail_in) { + sub_stream_->BackUp(zcontext_.avail_in); + } + if (zcontext_.next_out != NULL) { + // sub_stream_ may have concatenated streams to follow + zerror_ = inflateEnd(&zcontext_); + if (zerror_ != Z_OK) { + return false; + } + zerror_ = internalInflateInit2(&zcontext_, format_); + if (zerror_ != Z_OK) { + return false; + } + } else { + *data = NULL; + *size = 0; + return false; + } + } + zerror_ = Inflate(Z_NO_FLUSH); + if ((zerror_ == Z_STREAM_END) && (zcontext_.next_out == NULL)) { + // The underlying stream's Next returned false inside Inflate. + return false; + } + ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END) + || (zerror_ == Z_BUF_ERROR); + if (!ok) { + return false; + } + DoNextOutput(data, size); + return true; +} + +bool GzipInputStream::ExpectAtEnd() { + if (zerror_ == Z_STREAM_END) return true; + bool ok = (zerror_ == Z_OK) || (zerror_ == Z_BUF_ERROR); + if (!ok) { + return false; + } + const void* data; + int size = 0; + while (size == 0) { + bool ok = Next(&data, &size); + if (zerror_ == Z_STREAM_END) return true; + if (!ok) { + return false; + } + } + BackUp(size); + return false; +} + +void GzipInputStream::BackUp(int count) { + output_position_ = reinterpret_cast( + reinterpret_cast(output_position_) - count); +} + +bool GzipInputStream::Skip(int count) { + const void* data; + int size; + bool ok = Next(&data, &size); + while (ok && (size < count)) { + count -= size; + ok = Next(&data, &size); + } + if (size > count) { + BackUp(size - count); + } + return ok; +} + +int64 GzipInputStream::ByteCount() const { + return zcontext_.total_out + + (((uintptr_t)zcontext_.next_out) - ((uintptr_t)output_position_)); +} + +// ========================================================================= + +GzipOutputStream::Options::Options() + : format(GZIP), + buffer_size(kDefaultBufferSize), + compression_level(Z_DEFAULT_COMPRESSION), + compression_strategy(Z_DEFAULT_STRATEGY) {} + +GzipOutputStream::GzipOutputStream(ZeroCopyOutputStream* sub_stream) { + Init(sub_stream, Options()); +} + +GzipOutputStream::GzipOutputStream(ZeroCopyOutputStream* sub_stream, + const Options& options) { + Init(sub_stream, options); +} + +GzipOutputStream::GzipOutputStream( + ZeroCopyOutputStream* sub_stream, Format format, int buffer_size) { + Options options; + options.format = format; + if (buffer_size != -1) { + options.buffer_size = buffer_size; + } + Init(sub_stream, options); +} + +void GzipOutputStream::Init(ZeroCopyOutputStream* sub_stream, + const Options& options) { + sub_stream_ = sub_stream; + sub_data_ = NULL; + sub_data_size_ = 0; + + input_buffer_length_ = options.buffer_size; + input_buffer_ = operator new(input_buffer_length_); + GOOGLE_CHECK(input_buffer_ != NULL); + + zcontext_.zalloc = Z_NULL; + zcontext_.zfree = Z_NULL; + zcontext_.opaque = Z_NULL; + zcontext_.next_out = NULL; + zcontext_.avail_out = 0; + zcontext_.total_out = 0; + zcontext_.next_in = NULL; + zcontext_.avail_in = 0; + zcontext_.total_in = 0; + zcontext_.msg = NULL; + // default to GZIP format + int windowBitsFormat = 16; + if (options.format == ZLIB) { + windowBitsFormat = 0; + } + zerror_ = deflateInit2( + &zcontext_, + options.compression_level, + Z_DEFLATED, + /* windowBits */15 | windowBitsFormat, + /* memLevel (default) */8, + options.compression_strategy); +} + +GzipOutputStream::~GzipOutputStream() { + Close(); + if (input_buffer_ != NULL) { + operator delete(input_buffer_); + } +} + +// private +int GzipOutputStream::Deflate(int flush) { + int error = Z_OK; + do { + if ((sub_data_ == NULL) || (zcontext_.avail_out == 0)) { + bool ok = sub_stream_->Next(&sub_data_, &sub_data_size_); + if (!ok) { + sub_data_ = NULL; + sub_data_size_ = 0; + return Z_BUF_ERROR; + } + GOOGLE_CHECK_GT(sub_data_size_, 0); + zcontext_.next_out = static_cast(sub_data_); + zcontext_.avail_out = sub_data_size_; + } + error = deflate(&zcontext_, flush); + } while (error == Z_OK && zcontext_.avail_out == 0); + if ((flush == Z_FULL_FLUSH) || (flush == Z_FINISH)) { + // Notify lower layer of data. + sub_stream_->BackUp(zcontext_.avail_out); + // We don't own the buffer anymore. + sub_data_ = NULL; + sub_data_size_ = 0; + } + return error; +} + +// implements ZeroCopyOutputStream --------------------------------- +bool GzipOutputStream::Next(void** data, int* size) { + if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) { + return false; + } + if (zcontext_.avail_in != 0) { + zerror_ = Deflate(Z_NO_FLUSH); + if (zerror_ != Z_OK) { + return false; + } + } + if (zcontext_.avail_in == 0) { + // all input was consumed. reset the buffer. + zcontext_.next_in = static_cast(input_buffer_); + zcontext_.avail_in = input_buffer_length_; + *data = input_buffer_; + *size = input_buffer_length_; + } else { + // The loop in Deflate should consume all avail_in + GOOGLE_LOG(DFATAL) << "Deflate left bytes unconsumed"; + } + return true; +} +void GzipOutputStream::BackUp(int count) { + GOOGLE_CHECK_GE(int(zcontext_.avail_in), count); + zcontext_.avail_in -= count; +} +int64 GzipOutputStream::ByteCount() const { + return zcontext_.total_in + zcontext_.avail_in; +} + +bool GzipOutputStream::Flush() { + do { + zerror_ = Deflate(Z_FULL_FLUSH); + } while (zerror_ == Z_OK); + return zerror_ == Z_OK; +} + +bool GzipOutputStream::Close() { + if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) { + return false; + } + do { + zerror_ = Deflate(Z_FINISH); + } while (zerror_ == Z_OK); + zerror_ = deflateEnd(&zcontext_); + bool ok = zerror_ == Z_OK; + zerror_ = Z_STREAM_END; + return ok; +} + +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/gzip_stream.h b/src/sofa/pbrpc/gzip_stream.h new file mode 100644 index 0000000..282c8f3 --- /dev/null +++ b/src/sofa/pbrpc/gzip_stream.h @@ -0,0 +1,228 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from Protocal Buffers. +// +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: brianolson@google.com (Brian Olson) +// +// This file contains the definition for classes GzipInputStream and +// GzipOutputStream. +// +// GzipInputStream decompresses data from an underlying +// ZeroCopyInputStream and provides the decompressed data as a +// ZeroCopyInputStream. +// +// GzipOutputStream is an ZeroCopyOutputStream that compresses data to +// an underlying ZeroCopyOutputStream. +// +// Modifications by Johannes Ebke: Add ExpectAtEnd + +#ifndef _SOFA_PBRPC_GZIP_STREAM_H_ +#define _SOFA_PBRPC_GZIP_STREAM_H_ + +#include + +#include + +#include + +namespace sofa { +namespace pbrpc { + +using google::protobuf::io::ZeroCopyOutputStream; +using google::protobuf::io::ZeroCopyInputStream; +using google::protobuf::int64; + +// A ZeroCopyInputStream that reads compressed data through zlib +class GzipInputStream : public AbstractCompressedInputStream { + + public: + // Format key for constructor + enum Format { + // zlib will autodetect gzip header or deflate stream + AUTO = 0, + + // GZIP streams have some extra header data for file attributes. + GZIP = 1, + + // Simpler zlib stream format. + ZLIB = 2, + }; + + // buffer_size and format may be -1 for default of 64kB and GZIP format + explicit GzipInputStream( + ZeroCopyInputStream* sub_stream, + Format format = AUTO, + int buffer_size = -1); + virtual ~GzipInputStream(); + + // Return last error message or NULL if no error. + inline const char* ZlibErrorMessage() const { + return zcontext_.msg; + } + inline int ZlibErrorCode() const { + return zerror_; + } + + // Returns true if the compressed stream is at an end + // Reads zlib footer, so one can continue reading the + // underlying stream after this stream is deleted. + bool ExpectAtEnd(); + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size); + void BackUp(int count); + bool Skip(int count); + int64 ByteCount() const; + + private: + Format format_; + + ZeroCopyInputStream* sub_stream_; + + z_stream zcontext_; + int zerror_; + + void* output_buffer_; + void* output_position_; + size_t output_buffer_length_; + + int Inflate(int flush); + void DoNextOutput(const void** data, int* size); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipInputStream); +}; + +class GzipOutputStream : public AbstractCompressedOutputStream { + public: + // Format key for constructor + enum Format { + // GZIP streams have some extra header data for file attributes. + GZIP = 1, + + // Simpler zlib stream format. + ZLIB = 2, + }; + + struct Options { + // Defaults to GZIP. + Format format; + + // What size buffer to use internally. Defaults to 64kB. + int buffer_size; + + // A number between 0 and 9, where 0 is no compression and 9 is best + // compression. Defaults to Z_DEFAULT_COMPRESSION (see zlib.h). + int compression_level; + + // Defaults to Z_DEFAULT_STRATEGY. Can also be set to Z_FILTERED, + // Z_HUFFMAN_ONLY, or Z_RLE. See the documentation for deflateInit2 in + // zlib.h for definitions of these constants. + int compression_strategy; + + Options(); // Initializes with default values. + }; + + // Create a GzipOutputStream with default options. + explicit GzipOutputStream(ZeroCopyOutputStream* sub_stream); + + // Create a GzipOutputStream with the given options. + GzipOutputStream( + ZeroCopyOutputStream* sub_stream, + const Options& options); + + // DEPRECATED: Use one of the above constructors instead. + GzipOutputStream( + ZeroCopyOutputStream* sub_stream, + Format format, + int buffer_size = -1) GOOGLE_ATTRIBUTE_DEPRECATED; + + virtual ~GzipOutputStream(); + + // Return last error message or NULL if no error. + inline const char* ZlibErrorMessage() const { + return zcontext_.msg; + } + inline int ZlibErrorCode() const { + return zerror_; + } + + // Flushes data written so far to zipped data in the underlying stream. + // It is the caller's responsibility to flush the underlying stream if + // necessary. + // Compression may be less efficient stopping and starting around flushes. + // Returns true if no error. + virtual bool Flush(); + + // Writes out all data and closes the gzip stream. + // It is the caller's responsibility to close the underlying stream if + // necessary. + // Returns true if no error. + virtual bool Close(); + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size); + void BackUp(int count); + int64 ByteCount() const; + + private: + ZeroCopyOutputStream* sub_stream_; + // Result from calling Next() on sub_stream_ + void* sub_data_; + int sub_data_size_; + + z_stream zcontext_; + int zerror_; + void* input_buffer_; + size_t input_buffer_length_; + + // Shared constructor code. + void Init(ZeroCopyOutputStream* sub_stream, const Options& options); + + // Do some compression. + // Takes zlib flush mode. + // Returns zlib error code. + int Deflate(int flush); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipOutputStream); +}; + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_GZIP_STREAM_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/http-agent/http_agent.cc b/src/sofa/pbrpc/http-agent/http_agent.cc new file mode 100644 index 0000000..1e69713 --- /dev/null +++ b/src/sofa/pbrpc/http-agent/http_agent.cc @@ -0,0 +1,282 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include +#include + +#include +#include +#include + +namespace sofa { +namespace pbrpc { +namespace http_agent { + +HttpAgent::HttpAgent(RpcClient* rpc_client) + : _rpc_client(rpc_client) + , _rpc_channel(NULL) + , _stub(NULL) + , _desc_pool(NULL) + , _msg_factory(NULL) +{ +} + +HttpAgent::~HttpAgent() +{ + delete _msg_factory; + delete _desc_pool; + delete _stub; + delete _rpc_channel; +} + +bool HttpAgent::Init(const std::string& server_address) +{ + _server_address = server_address; + _rpc_channel = new RpcChannel(_rpc_client, _server_address); + if (!_rpc_channel->IsAddressValid()) { + delete _rpc_channel; + _rpc_channel = NULL; + return false; + } + _stub = new sofa::pbrpc::builtin::BuiltinService_Stub(_rpc_channel); + return UpdateServiceInfo(); +} + +bool HttpAgent::UpdateServiceInfo() +{ + if (_rpc_channel == NULL) return false; + RpcController cntl; + cntl.SetTimeout(3000); + sofa::pbrpc::builtin::ListServiceRequest request; + sofa::pbrpc::builtin::ListServiceResponse response; + _stub->ListService(&cntl, &request, &response, NULL); + if (cntl.Failed()) { + SLOG(ERROR, "UpdateServiceInfo(): call ListService failed: %s", cntl.ErrorText().c_str()); + return false; + } + + WriteLocker _(&_desc_lock); + if (_desc_pool != NULL) { + delete _desc_pool; + _desc_pool = NULL; + delete _msg_factory; + _msg_factory = NULL; + _svc_desc_map.clear(); + } + _desc_pool = new ::google::protobuf::DescriptorPool(); + for (int i = 0; i < response.files_size(); ++i) { + const ::google::protobuf::FileDescriptorProto& d = response.files(i); + const ::google::protobuf::FileDescriptor* fd = _desc_pool->BuildFile(d); + if (fd == NULL) { + SLOG(ERROR, "UpdateServiceInfo(): build file descriptor failed: %s", d.name().c_str()); + delete _desc_pool; + _desc_pool = NULL; + return false; + } + SLOG(INFO, "UpdateServiceInfo(): add file [%s]", d.name().c_str()); + } + for (int j = 0; j < response.services_size(); ++j) { + const std::string& s = response.services(j); + SLOG(INFO, "UpdateServiceInfo(): add service [%s]", s.c_str()); + const ::google::protobuf::ServiceDescriptor* sd = _desc_pool->FindServiceByName(s); + if (sd == NULL) { + SLOG(ERROR, "UpdateServiceInfo(): find service descriptor failed: %s", s.c_str()); + delete _desc_pool; + _desc_pool = NULL; + return false; + } + _svc_desc_map[s] = sd; + } + _msg_factory = new ::google::protobuf::DynamicMessageFactory(_desc_pool); + return true; +} + +bool HttpAgent::ListService(std::map* service_map) +{ + ReadLocker _(&_desc_lock); + if (_desc_pool == NULL) { + SLOG(ERROR, "ListService(): descriptor pool not exist"); + return false; + } + + for (ServiceDescriptorMap::iterator it = _svc_desc_map.begin(); + it != _svc_desc_map.end(); ++it) { + const ::google::protobuf::ServiceDescriptor* sd = it->second; + ::google::protobuf::ServiceDescriptorProto& sdp = (*service_map)[sd->full_name()]; + sd->CopyTo(&sdp); + } + return true; +} + +bool HttpAgent::ListService(std::map* desc_map) +{ + ReadLocker _(&_desc_lock); + if (_desc_pool == NULL) { + SLOG(ERROR, "ListService(): descriptor pool not exist"); + return false; + } + + for (ServiceDescriptorMap::iterator it = _svc_desc_map.begin(); + it != _svc_desc_map.end(); ++it) { + const ::google::protobuf::ServiceDescriptor* sd = it->second; + (*desc_map)[sd->full_name()] = sd->DebugString(); + } + return true; +} + +bool HttpAgent::GetDescriptor(const std::string& name, ProtobufType* type, std::string* desc) +{ + ReadLocker _(&_desc_lock); + if (_desc_pool == NULL) { + SLOG(ERROR, "GetDescriptor(): descriptor pool not exist"); + return false; + } + + const ::google::protobuf::ServiceDescriptor* sd = _desc_pool->FindServiceByName(name); + if (sd != NULL) { + *type = PT_SERVICE; + *desc = sd->DebugString(); + return true; + } + + const ::google::protobuf::Descriptor* d = _desc_pool->FindMessageTypeByName(name); + if (d != NULL) { + *type = PT_MESSAGE; + *desc = d->DebugString(); + return true; + } + + const ::google::protobuf::EnumDescriptor* ed = _desc_pool->FindEnumTypeByName(name); + if (ed != NULL) { + *type = PT_ENUM; + *desc = ed->DebugString(); + return true; + } + + SLOG(ERROR, "GetDescriptor(): type not found: %s", name.c_str()); + return false; +} + +void HttpAgent::CallMethod(const std::string& method_full_name, + ::google::protobuf::RpcController* controller, + const std::string* request, + std::string* response, + ::google::protobuf::Closure* done) +{ + SCHECK(controller != NULL); + SCHECK(request != NULL); + SCHECK(response != NULL); + + RpcController* sofa_controller = dynamic_cast(controller); + SCHECK(sofa_controller != NULL); // should pass sofa::pbrpc::RpcController to CallMethod + RpcControllerImplPtr cntl = sofa_controller->impl(); + + if (_rpc_channel == NULL) { + SLOG(ERROR, "CallMethod(): server not avaliable"); + cntl->SetFailed(RPC_ERROR_CREATE_STREAM, "server not avaliable"); + if (done != NULL) done->Run(); + return; + } + + if (_desc_pool == NULL && !UpdateServiceInfo()) { + SLOG(ERROR, "CallMethod(): fetch service descriptor from server failed"); + cntl->SetFailed(RPC_ERROR_CREATE_STREAM, "fetch service descriptor from server failed"); + if (done != NULL) done->Run(); + return; + } + + std::string service_full_name; + std::string method_name; + if (!ParseMethodFullName(method_full_name, &service_full_name, &method_name)) { + SLOG(ERROR, "CallMethod(): invalid method name: %s", method_full_name.c_str()); + cntl->SetFailed(RPC_ERROR_PARSE_METHOD_NAME, "invalid method name"); + if (done != NULL) done->Run(); + return; + } + + ReadLocker _(&_desc_lock); + ServiceDescriptorMap::iterator find = _svc_desc_map.find(service_full_name); + if (find == _svc_desc_map.end()) { + SLOG(ERROR, "CallMethod(): service not found: %s", service_full_name.c_str()); + cntl->SetFailed(RPC_ERROR_FOUND_SERVICE, "service not found"); + if (done != NULL) done->Run(); + return; + } + const ::google::protobuf::ServiceDescriptor* sd = find->second; + const ::google::protobuf::MethodDescriptor* md = sd->FindMethodByName(method_name); + if (md == NULL) { + SLOG(ERROR, "CallMethod(): method not found: %s", method_full_name.c_str()); + cntl->SetFailed(RPC_ERROR_FOUND_METHOD, "method not found"); + if (done != NULL) done->Run(); + return; + } + const ::google::protobuf::Descriptor* id = md->input_type(); + const ::google::protobuf::Descriptor* od = md->output_type(); + ::google::protobuf::Message* request_message = _msg_factory->GetPrototype(id)->New(); + if (!::google::protobuf::TextFormat::ParseFromString(*request, request_message)) { + delete request_message; + SLOG(ERROR, "CallMethod(): parse request message failed"); + cntl->SetFailed(RPC_ERROR_PARSE_REQUEST_MESSAGE, "parse request message failed"); + if (done != NULL) done->Run(); + return; + } + ::google::protobuf::Message* response_message = _msg_factory->GetPrototype(od)->New(); + ::google::protobuf::Closure* real_done = NULL; + if (done == NULL) { + // sync call + real_done = done; + } + else { + // async call + real_done = NewClosure(&HttpAgent::CallMethodDone, + cntl, response, request_message, response_message, done); + } + _rpc_channel->CallMethod(md, controller, request_message, response_message, real_done); + if (done == NULL) { + // sync call + if (!cntl->Failed()) { + if (!::google::protobuf::TextFormat::PrintToString(*response_message, response)) { + SLOG(ERROR, "CallMethod(): print response message failed"); + cntl->SetFailed(RPC_ERROR_SERIALIZE_RESPONSE, "print response message failed"); + } + } + delete request_message; + delete response_message; + } +} + +void HttpAgent::CallMethodDone(const RpcControllerImplPtr& cntl, + std::string* response, + ::google::protobuf::Message* request_message, + ::google::protobuf::Message* response_message, + ::google::protobuf::Closure* done) +{ + if (!cntl->Failed()) { + if (!::google::protobuf::TextFormat::PrintToString(*response_message, response)) { + SLOG(ERROR, "CallMethod(): print response message failed"); + cntl->SetFailed(RPC_ERROR_SERIALIZE_RESPONSE, "print response message failed"); + } + } + delete request_message; + delete response_message; + done->Run(); +} + +bool HttpAgent::ParseMethodFullName(const std::string& method_full_name, + std::string* service_full_name, std::string* method_name) +{ + std::string::size_type pos = method_full_name.rfind('.'); + if (pos == std::string::npos) return false; + *service_full_name = method_full_name.substr(0, pos); + *method_name = method_full_name.substr(pos + 1); + return true; +} + +} // namespace http_agent +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/http-agent/http_agent.h b/src/sofa/pbrpc/http-agent/http_agent.h new file mode 100644 index 0000000..ba5ba26 --- /dev/null +++ b/src/sofa/pbrpc/http-agent/http_agent.h @@ -0,0 +1,87 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBPRC_HTTP_AGENT_HTTP_AGENT_H_ +#define _SOFA_PBPRC_HTTP_AGENT_HTTP_AGENT_H_ + +#include +#include + +#include +#include +#include + +#include + +namespace sofa { +namespace pbrpc { + +class RpcControllerImpl; + +namespace builtin { +class BuiltinService_Stub; +} // namespace builtin + +namespace http_agent { + +class HttpAgent +{ +public: + HttpAgent(RpcClient* rpc_client); + ~HttpAgent(); + + bool Init(const std::string& server_address); + + bool UpdateServiceInfo(); + + bool ListService(std::map* service_map); + + // Returns map: name --> desc + bool ListService(std::map* desc_map); + + enum ProtobufType { + PT_SERVICE, + PT_MESSAGE, + PT_ENUM, + }; + bool GetDescriptor(const std::string& name, ProtobufType* type, std::string* desc); + + void CallMethod(const std::string& method_full_name, + ::google::protobuf::RpcController* controller, + const std::string* request, + std::string* response, + ::google::protobuf::Closure* done); + +private: + static void CallMethodDone(const sofa::pbrpc::shared_ptr& cntl, + std::string* response, + ::google::protobuf::Message* request_message, + ::google::protobuf::Message* response_message, + ::google::protobuf::Closure* done); + + bool ParseMethodFullName(const std::string& method_full_name, + std::string* service_full_name, std::string* method_name); + +private: + RpcClient* _rpc_client; + RpcChannel* _rpc_channel; + sofa::pbrpc::builtin::BuiltinService_Stub* _stub; + std::string _server_address; + + RWLock _desc_lock; + ::google::protobuf::DescriptorPool* _desc_pool; + ::google::protobuf::MessageFactory* _msg_factory; + typedef std::map ServiceDescriptorMap; + ServiceDescriptorMap _svc_desc_map; +}; + +} // namespace http_agent +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBPRC_HTTP_AGENT_HTTP_AGENT_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/http-agent/sofa_pbrpc_client.cc b/src/sofa/pbrpc/http-agent/sofa_pbrpc_client.cc new file mode 100644 index 0000000..121f1ce --- /dev/null +++ b/src/sofa/pbrpc/http-agent/sofa_pbrpc_client.cc @@ -0,0 +1,340 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include +#include + +#include +#include +#include + +static std::string g_server_address; + +void usage(); +void error(const std::string& message, bool print_usage); +int run_health(int argc, const char** argv); +int run_status(int argc, const char** argv); +int run_option(int argc, const char** argv); +int run_stat(int argc, const char** argv); +int run_list(int argc, const char** argv); +int run_desc(int argc, const char** argv); +int run_call(int argc, const char** argv); +int call_method(std::string method, std::string request, int timeout); + +void usage() { + fprintf(stderr, + "Usage: sofa-pbrpc-client [args]\n" + "\n" + "Available subcommands:\n" + " help\n" + " Print this usage help.\n" + "\n" + " health \n" + " Check if the server is healthy.\n" + "\n" + " status \n" + " Get status of the server.\n" + "\n" + " option \n" + " Get RpcServerOptions of the server.\n" + "\n" + " list \n" + " List all services provided by the server.\n" + "\n" + " desc \n" + " Get descriptor of a protobuf type (service/message/enum).\n" + "\n" + " call [timeout-in-ms]\n" + " Call a method using the text format of request message.\n" + " The \"timeout-in-ms\" is optional, default is 3000 milli-seconds.\n" + "\n" + " stat [service-full-name] [period-in-seconds]\n" + " Get the service statistics in the latest period of seconds.\n" + " The \"service-full-name\" is optional, default is \"all\".\n" + " The \"period-in-seconds\" is optional, default is 60 seconds.\n" + "\n" + "For more usage help, please see:\n" + ".\n" + ); +} + +void error(const std::string& message, bool print_usage) +{ + fprintf(stderr, "***** ERROR: %s *****\n", message.c_str()); + if (print_usage) { + fprintf(stderr, "\n"); + usage(); + } +} + +int run_health(int /*argc*/, const char** /*argv*/) +{ + sofa::pbrpc::RpcClient rpc_client; + sofa::pbrpc::RpcChannel rpc_channel(&rpc_client, g_server_address); + sofa::pbrpc::builtin::BuiltinService_Stub stub(&rpc_channel); + + sofa::pbrpc::RpcController cntl; + sofa::pbrpc::builtin::HealthRequest request; + sofa::pbrpc::builtin::HealthResponse response; + stub.Health(&cntl, &request, &response, NULL); + if (cntl.Failed()) { + error("call method failed: " + cntl.ErrorText(), false); + return EXIT_FAILURE; + } + else { + fprintf(stdout, + "Response:\n" + "------------------------------\n" + "%s" + "------------------------------\n", + response.DebugString().c_str()); + return EXIT_SUCCESS; + } +} + +int run_status(int /*argc*/, const char** /*argv*/) +{ + sofa::pbrpc::RpcClient rpc_client; + sofa::pbrpc::RpcChannel rpc_channel(&rpc_client, g_server_address); + sofa::pbrpc::builtin::BuiltinService_Stub stub(&rpc_channel); + + sofa::pbrpc::RpcController cntl; + sofa::pbrpc::builtin::ServerStatusRequest request; + sofa::pbrpc::builtin::ServerStatusResponse response; + stub.ServerStatus(&cntl, &request, &response, NULL); + if (cntl.Failed()) { + error("call method failed: " + cntl.ErrorText(), false); + return EXIT_FAILURE; + } + else { + fprintf(stdout, + "Response:\n" + "------------------------------\n" + "%s" + "------------------------------\n", + response.DebugString().c_str()); + return EXIT_SUCCESS; + } +} + +int run_option(int /*argc*/, const char** /*argv*/) +{ + sofa::pbrpc::RpcClient rpc_client; + sofa::pbrpc::RpcChannel rpc_channel(&rpc_client, g_server_address); + sofa::pbrpc::builtin::BuiltinService_Stub stub(&rpc_channel); + + sofa::pbrpc::RpcController cntl; + sofa::pbrpc::builtin::ServerOptionsRequest request; + sofa::pbrpc::builtin::ServerOptionsResponse response; + stub.ServerOptions(&cntl, &request, &response, NULL); + if (cntl.Failed()) { + error("call method failed: " + cntl.ErrorText(), false); + return EXIT_FAILURE; + } + else { + fprintf(stdout, + "Response:\n" + "------------------------------\n" + "%s" + "------------------------------\n", + response.DebugString().c_str()); + return EXIT_SUCCESS; + } +} + +int run_stat(int argc, const char** argv) +{ + sofa::pbrpc::RpcClient rpc_client; + sofa::pbrpc::RpcChannel rpc_channel(&rpc_client, g_server_address); + sofa::pbrpc::builtin::BuiltinService_Stub stub(&rpc_channel); + + sofa::pbrpc::RpcController cntl; + sofa::pbrpc::builtin::StatRequest request; + if (argc >= 1) { + request.set_service_name(argv[0]); + } + else { + request.set_service_name("all"); + } + if (argc >= 2) { + request.set_period_seconds(atoi(argv[1])); + } + else { + request.set_period_seconds(60); + } + sofa::pbrpc::builtin::StatResponse response; + stub.Stat(&cntl, &request, &response, NULL); + if (cntl.Failed()) { + error("call method failed: " + cntl.ErrorText(), false); + return EXIT_FAILURE; + } + else { + fprintf(stdout, + "Response:\n" + "------------------------------\n" + "%s" + "------------------------------\n", + response.DebugString().c_str()); + return EXIT_SUCCESS; + } +} + + +int run_list(int /*argc*/, const char** /*argv*/) +{ + sofa::pbrpc::RpcClient rpc_client; + sofa::pbrpc::http_agent::HttpAgent agent(&rpc_client); + if (!agent.Init(g_server_address)) { + error("init failed", false); + return EXIT_FAILURE; + } + std::map desc_map; + if (!agent.ListService(&desc_map)) { + error("list failed", false); + return EXIT_FAILURE; + } + for (std::map::iterator it = desc_map.begin(); + it != desc_map.end(); ++it) { + if (it != desc_map.begin()) fprintf(stderr, "\n"); + fprintf(stderr, + "Service [%s]:\n" + "------------------------------\n" + "%s" + "------------------------------\n", + it->first.c_str(), it->second.c_str()); + } + return EXIT_SUCCESS; +} + +int run_desc(int argc, const char** argv) +{ + if (argc < 1) { + error("no enough arguments", true); + return EXIT_FAILURE; + } + std::string name = argv[0]; + if (name.find('.') == 0) { + // remove leading '.' + name = name.substr(1); + } + sofa::pbrpc::RpcClient rpc_client; + sofa::pbrpc::http_agent::HttpAgent agent(&rpc_client); + if (!agent.Init(g_server_address)) { + error("init failed", false); + return EXIT_FAILURE; + } + sofa::pbrpc::http_agent::HttpAgent::ProtobufType type; + std::string desc; + if (!agent.GetDescriptor(name, &type, &desc)) { + error("type not found", false); + return EXIT_FAILURE; + } + std::string type_str; + if (type == sofa::pbrpc::http_agent::HttpAgent::PT_SERVICE) { + type_str = "Service"; + } + else if (type == sofa::pbrpc::http_agent::HttpAgent::PT_MESSAGE) { + type_str = "Message"; + } + else if (type == sofa::pbrpc::http_agent::HttpAgent::PT_ENUM) { + type_str = "Enum"; + } + else { + type_str = "Unknown"; + } + fprintf(stdout, + "Descriptor of [%s]:\n" + "------------------------------\n" + "%s" + "------------------------------\n", + name.c_str(), desc.c_str()); + return EXIT_SUCCESS; +} + +int run_call(int argc, const char** argv) +{ + if (argc < 2) { + error("no enough arguments", true); + return EXIT_FAILURE; + } + int timeout = 3000; + if (argc >= 3) { + timeout = atoi(argv[3]); + } + return call_method(argv[0], argv[1], timeout); +} + +int call_method(std::string method, std::string request, int timeout) +{ + sofa::pbrpc::RpcClient rpc_client; + sofa::pbrpc::http_agent::HttpAgent agent(&rpc_client); + if (!agent.Init(g_server_address)) { + error("init failed", false); + return EXIT_FAILURE; + } + + sofa::pbrpc::RpcController cntl; + cntl.SetTimeout(timeout); + std::string response; + agent.CallMethod(method, &cntl, &request, &response, NULL); + if (cntl.Failed()) { + error("call method failed: " + cntl.ErrorText(), false); + return EXIT_FAILURE; + } + else { + fprintf(stdout, + "Response:\n" + "------------------------------\n" + "%s" + "------------------------------\n", + response.c_str()); + return EXIT_SUCCESS; + } +} + +int main(int argc, const char** argv) +{ + if (argc < 3) { + error("no enough arguments", true); + return EXIT_SUCCESS; + } + + g_server_address = argv[1]; + std::string cmd = argv[2]; + argc = argc - 3; + argv = argv + 3; + if (g_server_address == "help" || cmd == "help") { + usage(); + return EXIT_SUCCESS; + } + else if (cmd == "health") { + return run_health(argc, argv); + } + else if (cmd == "status") { + return run_status(argc, argv); + } + else if (cmd == "option") { + return run_option(argc, argv); + } + else if (cmd == "stat") { + return run_stat(argc, argv); + } + else if (cmd == "list") { + return run_list(argc, argv); + } + else if (cmd == "desc") { + return run_desc(argc, argv); + } + else if (cmd == "call") { + return run_call(argc, argv); + } + else { + error("invalid command", true); + return EXIT_FAILURE; + } +} + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/io_service.h b/src/sofa/pbrpc/io_service.h new file mode 100644 index 0000000..1ad5f3a --- /dev/null +++ b/src/sofa/pbrpc/io_service.h @@ -0,0 +1,60 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_IO_SERVICE_H_ +#define _SOFA_PBRPC_IO_SERVICE_H_ + +/************************************************************************* + * ATTENTION: we suppose that epoll is always supported on the platform. + +// Linux: epoll, eventfd and timerfd. +#if defined(__linux__) +# include +# if !defined(BOOST_ASIO_DISABLE_EPOLL) +# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45) +# define BOOST_ASIO_HAS_EPOLL 1 +# endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45) +# endif // !defined(BOOST_ASIO_DISABLE_EVENTFD) +# if !defined(BOOST_ASIO_DISABLE_EVENTFD) +# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) +# define BOOST_ASIO_HAS_EVENTFD 1 +# endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) +# endif // !defined(BOOST_ASIO_DISABLE_EVENTFD) +# if defined(BOOST_ASIO_HAS_EPOLL) +# if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8) +# define BOOST_ASIO_HAS_TIMERFD 1 +# endif // (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8) +# endif // defined(BOOST_ASIO_HAS_EPOLL) +#endif // defined(__linux__) + +**************************************************************************/ + +#define BOOST_ASIO_HAS_EPOLL 1 + +#include +#include + +namespace sofa { +namespace pbrpc { + +typedef boost::asio::io_service IOService; +typedef sofa::pbrpc::shared_ptr IOServicePtr; + +typedef boost::asio::io_service::work IOServiceWork; +typedef sofa::pbrpc::shared_ptr IOServiceWorkPtr; + +typedef boost::asio::io_service::strand IOServiceStrand; +typedef sofa::pbrpc::shared_ptr IOServiceStrandPtr; + +typedef boost::asio::deadline_timer IOServiceTimer; +typedef sofa::pbrpc::shared_ptr IOServiceTimerPtr; + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_IO_SERVICE_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/locks.h b/src/sofa/pbrpc/locks.h new file mode 100644 index 0000000..e5090c6 --- /dev/null +++ b/src/sofa/pbrpc/locks.h @@ -0,0 +1,19 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_LOCKS_H_ +#define _SOFA_PBRPC_LOCKS_H_ + +#include +#include +#include +#include +#include +#include + +#endif // _SOFA_PBRPC_LOCKS_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/lz4.cc b/src/sofa/pbrpc/lz4.cc new file mode 100644 index 0000000..9091b3f --- /dev/null +++ b/src/sofa/pbrpc/lz4.cc @@ -0,0 +1,833 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +/* + LZ4 - Fast LZ compression algorithm + Copyright (C) 2011-2012, Yann Collet. + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html + - LZ4 source repository : http://code.google.com/p/lz4/ +*/ + +//************************************** +// Tuning parameters +//************************************** +// COMPRESSIONLEVEL : +// Increasing this value improves compression ratio +// Lowering this value reduces memory usage +// Reduced memory usage typically improves speed, due to cache effect (ex : L1 32KB for Intel, L1 64KB for AMD) +// Memory usage formula : N->2^(N+2) Bytes (examples : 12 -> 16KB ; 17 -> 512KB) +#define COMPRESSIONLEVEL 12 + +// NOTCOMPRESSIBLE_CONFIRMATION : +// Decreasing this value will make the algorithm skip faster data segments considered "incompressible" +// This may decrease compression ratio dramatically, but will be faster on incompressible data +// Increasing this value will make the algorithm search more before declaring a segment "incompressible" +// This could improve compression a bit, but will be slower on incompressible data +// The default value (6) is recommended +#define NOTCOMPRESSIBLE_CONFIRMATION 6 + +// LZ4_COMPRESSMIN : +// Compression function will *fail* if it is not successful at compressing input by at least LZ4_COMPRESSMIN bytes +// Since the compression function stops working prematurely, it results in a speed gain +// The output however is unusable. Compression function result will be zero. +// Default : 0 = disabled +#define LZ4_COMPRESSMIN 0 + +// BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE : +// This will provide a boost to performance for big endian cpu, but the resulting compressed stream will be incompatible with little-endian CPU. +// You can set this option to 1 in situations where data will stay within closed environment +// This option is useless on Little_Endian CPU (such as x86) +//#define BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE 1 + + + +//************************************** +// CPU Feature Detection +//************************************** +// 32 or 64 bits ? +#if (defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || defined(__amd64) || defined(__ppc64__) || defined(_WIN64) || defined(__LP64__) || defined(_LP64) ) // Detects 64 bits mode +# define LZ4_ARCH64 1 +#else +# define LZ4_ARCH64 0 +#endif + +// Little Endian or Big Endian ? +// Note : overwrite the below #define if you know your architecture endianess +#if (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN) || defined(_ARCH_PPC) || defined(__PPC__) || defined(__PPC) || defined(PPC) || defined(__powerpc__) || defined(__powerpc) || defined(powerpc) || ((defined(__BYTE_ORDER__)&&(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))) ) +# define LZ4_BIG_ENDIAN 1 +#else +// Little Endian assumed. PDP Endian and other very rare endian format are unsupported. +#endif + +// Unaligned memory access is automatically enabled for "common" CPU, such as x86. +// For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected +// If you know your target CPU supports unaligned memory access, you may want to force this option manually to improve performance +#if defined(__ARM_FEATURE_UNALIGNED) +# define LZ4_FORCE_UNALIGNED_ACCESS 1 +#endif + +// Define this parameter if your target system or compiler does not support hardware bit count +#if defined(_MSC_VER) && defined(_WIN32_WCE) // Visual Studio for Windows CE does not support Hardware bit count +# define LZ4_FORCE_SW_BITCOUNT +#endif + + +//************************************** +// Compiler Options +//************************************** +#if __STDC_VERSION__ >= 199901L // C99 +/* "restrict" is a known keyword */ +#else +# define restrict // Disable restrict +#endif + +#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) + +#ifdef _MSC_VER // Visual Studio +# define inline __forceinline // Visual is not C99, but supports some kind of inline +# if LZ4_ARCH64 // 64-bit +# pragma intrinsic(_BitScanForward64) // For Visual 2005 +# pragma intrinsic(_BitScanReverse64) // For Visual 2005 +# else +# pragma intrinsic(_BitScanForward) // For Visual 2005 +# pragma intrinsic(_BitScanReverse) // For Visual 2005 +# endif +#endif + +#ifdef _MSC_VER +# define lz4_bswap16(x) _byteswap_ushort(x) +#else +# define lz4_bswap16(x) ((unsigned short int) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8))) +#endif + +#if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__) +# define expect(expr,value) (__builtin_expect ((expr),(value)) ) +#else +# define expect(expr,value) (expr) +#endif + +#define likely(expr) expect((expr) != 0, 1) +#define unlikely(expr) expect((expr) != 0, 0) + + +//************************************** +// Includes +//************************************** +#include // for malloc +#include // for memset +#include + + +//************************************** +// Basic Types +//************************************** +#if defined(_MSC_VER) // Visual Studio does not support 'stdint' natively +# define BYTE unsigned __int8 +# define U16 unsigned __int16 +# define U32 unsigned __int32 +# define S32 __int32 +# define U64 unsigned __int64 +#else +# include +# define BYTE uint8_t +# define U16 uint16_t +# define U32 uint32_t +# define S32 int32_t +# define U64 uint64_t +#endif + +#ifndef LZ4_FORCE_UNALIGNED_ACCESS +# pragma pack(push, 1) +#endif + +typedef struct _U16_S { U16 v; } U16_S; +typedef struct _U32_S { U32 v; } U32_S; +typedef struct _U64_S { U64 v; } U64_S; + +#ifndef LZ4_FORCE_UNALIGNED_ACCESS +# pragma pack(pop) +#endif + +#define A64(x) (((U64_S *)(x))->v) +#define A32(x) (((U32_S *)(x))->v) +#define A16(x) (((U16_S *)(x))->v) + + +//************************************** +// Constants +//************************************** +#define MINMATCH 4 + +#define HASH_LOG COMPRESSIONLEVEL +#define HASHTABLESIZE (1 << HASH_LOG) +#define HASH_MASK (HASHTABLESIZE - 1) + +#define SKIPSTRENGTH (NOTCOMPRESSIBLE_CONFIRMATION>2?NOTCOMPRESSIBLE_CONFIRMATION:2) +#define STACKLIMIT 13 +#define HEAPMODE (HASH_LOG>STACKLIMIT) // Defines if memory is allocated into the stack (local variable), or into the heap (malloc()). +#define COPYLENGTH 8 +#define LASTLITERALS 5 +#define MFLIMIT (COPYLENGTH+MINMATCH) +#define MINLENGTH (MFLIMIT+1) + +#define MAXD_LOG 16 +#define MAX_DISTANCE ((1 << MAXD_LOG) - 1) + +#define ML_BITS 4 +#define ML_MASK ((1U<> ((MINMATCH*8)-HASH_LOG)) +#define LZ4_HASH_VALUE(p) LZ4_HASH_FUNCTION(A32(p)) +#define LZ4_WILDCOPY(s,d,e) do { LZ4_COPYPACKET(s,d) } while (d>3); + #elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (__builtin_clzll(val) >> 3); + #else + int r; + if (!(val>>32)) { r=4; } else { r=0; val>>=32; } + if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; } + r += (!val); + return r; + #endif +#else + #if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) + unsigned long r = 0; + _BitScanForward64( &r, val ); + return (int)(r>>3); + #elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (__builtin_ctzll(val) >> 3); + #else + static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 }; + return DeBruijnBytePos[((U64)((val & -val) * 0x0218A392CDABBD3F)) >> 58]; + #endif +#endif +} + +#else + +inline static int LZ4_NbCommonBytes (register U32 val) +{ +#if defined(LZ4_BIG_ENDIAN) + #if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) + unsigned long r = 0; + _BitScanReverse( &r, val ); + return (int)(r>>3); + #elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (__builtin_clz(val) >> 3); + #else + int r; + if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; } + r += (!val); + return r; + #endif +#else + #if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) + unsigned long r = 0; + _BitScanForward( &r, val ); + return (int)(r>>3); + #elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (__builtin_ctz(val) >> 3); + #else + static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 }; + return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27]; + #endif +#endif +} + +#endif + + +//**************************** +// Public functions +//**************************** + +int LZ4_compressBound(int isize) +{ + return (isize + (isize/255) + 16); +} + + + +//****************************** +// Compression functions +//****************************** + +int LZ4_compressCtx(void** ctx, + const char* source, + char* dest, + int isize) +{ +#if HEAPMODE + struct refTables *srt = (struct refTables *) (*ctx); + HTYPE* HashTable; +#else + HTYPE HashTable[HASHTABLESIZE] = {0}; +#endif + + const BYTE* ip = (BYTE*) source; + INITBASE(base); + const BYTE* anchor = ip; + const BYTE* const iend = ip + isize; + const BYTE* const mflimit = iend - MFLIMIT; +#define matchlimit (iend - LASTLITERALS) + + BYTE* op = (BYTE*) dest; + + int len, length; + const int skipStrength = SKIPSTRENGTH; + U32 forwardH; + + + // Init + if (isizehashTable); + memset((void*)HashTable, 0, sizeof(srt->hashTable)); +#else + (void) ctx; +#endif + + + // First Byte + HashTable[LZ4_HASH_VALUE(ip)] = ip - base; + ip++; forwardH = LZ4_HASH_VALUE(ip); + + // Main Loop + for ( ; ; ) + { + int findMatchAttempts = (1U << skipStrength) + 3; + const BYTE* forwardIp = ip; + const BYTE* ref; + BYTE* token; + + // Find a match + do { + U32 h = forwardH; + int step = findMatchAttempts++ >> skipStrength; + ip = forwardIp; + forwardIp = ip + step; + + if unlikely(forwardIp > mflimit) { goto _last_literals; } + + forwardH = LZ4_HASH_VALUE(forwardIp); + ref = base + HashTable[h]; + HashTable[h] = ip - base; + + } while ((ref < ip - MAX_DISTANCE) || (A32(ref) != A32(ip))); + + // Catch up + while ((ip>anchor) && (ref>(BYTE*)source) && unlikely(ip[-1]==ref[-1])) { ip--; ref--; } + + // Encode Literal length + length = ip - anchor; + token = op++; + if (length>=(int)RUN_MASK) { *token=(RUN_MASK< 254 ; len-=255) *op++ = 255; *op++ = (BYTE)len; } + else *token = (length<=(int)ML_MASK) { *token+=ML_MASK; len-=ML_MASK; for(; len > 509 ; len-=510) { *op++ = 255; *op++ = 255; } if (len > 254) { len-=255; *op++ = 255; } *op++ = (BYTE)len; } + else *token += len; + + // Test end of chunk + if (ip > mflimit) { anchor = ip; break; } + + // Fill table + HashTable[LZ4_HASH_VALUE(ip-2)] = ip - 2 - base; + + // Test next position + ref = base + HashTable[LZ4_HASH_VALUE(ip)]; + HashTable[LZ4_HASH_VALUE(ip)] = ip - base; + if ((ref > ip - (MAX_DISTANCE + 1)) && (A32(ref) == A32(ip))) { token = op++; *token=0; goto _next_match; } + + // Prepare next loop + anchor = ip++; + forwardH = LZ4_HASH_VALUE(ip); + } + +_last_literals: + // Encode Last Literals + { + int lastRun = iend - anchor; + if ((LZ4_COMPRESSMIN>0) && (((op - (BYTE*)dest) + lastRun + 1 + ((lastRun-15)/255)) > isize - LZ4_COMPRESSMIN)) return 0; + if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK< 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; } + else *op++ = (lastRun<> ((MINMATCH*8)-HASHLOG64K)) +#define LZ4_HASH64K_VALUE(p) LZ4_HASH64K_FUNCTION(A32(p)) +int LZ4_compress64kCtx(void** ctx, + const char* source, + char* dest, + int isize) +{ +#if HEAPMODE + struct refTables *srt = (struct refTables *) (*ctx); + U16* HashTable; +#else + U16 HashTable[HASH64KTABLESIZE] = {0}; +#endif + + const BYTE* ip = (BYTE*) source; + const BYTE* anchor = ip; + const BYTE* const base = ip; + const BYTE* const iend = ip + isize; + const BYTE* const mflimit = iend - MFLIMIT; +#define matchlimit (iend - LASTLITERALS) + + BYTE* op = (BYTE*) dest; + + int len, length; + const int skipStrength = SKIPSTRENGTH; + U32 forwardH; + + + // Init + if (isizehashTable); + memset((void*)HashTable, 0, sizeof(srt->hashTable)); +#else + (void) ctx; +#endif + + + // First Byte + ip++; forwardH = LZ4_HASH64K_VALUE(ip); + + // Main Loop + for ( ; ; ) + { + int findMatchAttempts = (1U << skipStrength) + 3; + const BYTE* forwardIp = ip; + const BYTE* ref; + BYTE* token; + + // Find a match + do { + U32 h = forwardH; + int step = findMatchAttempts++ >> skipStrength; + ip = forwardIp; + forwardIp = ip + step; + + if (forwardIp > mflimit) { goto _last_literals; } + + forwardH = LZ4_HASH64K_VALUE(forwardIp); + ref = base + HashTable[h]; + HashTable[h] = ip - base; + + } while (A32(ref) != A32(ip)); + + // Catch up + while ((ip>anchor) && (ref>(BYTE*)source) && (ip[-1]==ref[-1])) { ip--; ref--; } + + // Encode Literal length + length = ip - anchor; + token = op++; + if (length>=(int)RUN_MASK) { *token=(RUN_MASK< 254 ; len-=255) *op++ = 255; *op++ = (BYTE)len; } + else *token = (length<=(int)ML_MASK) { *token+=ML_MASK; len-=ML_MASK; for(; len > 509 ; len-=510) { *op++ = 255; *op++ = 255; } if (len > 254) { len-=255; *op++ = 255; } *op++ = (BYTE)len; } + else *token += len; + + // Test end of chunk + if (ip > mflimit) { anchor = ip; break; } + + // Fill table + HashTable[LZ4_HASH64K_VALUE(ip-2)] = ip - 2 - base; + + // Test next position + ref = base + HashTable[LZ4_HASH64K_VALUE(ip)]; + HashTable[LZ4_HASH64K_VALUE(ip)] = ip - base; + if (A32(ref) == A32(ip)) { token = op++; *token=0; goto _next_match; } + + // Prepare next loop + anchor = ip++; + forwardH = LZ4_HASH64K_VALUE(ip); + } + +_last_literals: + // Encode Last Literals + { + int lastRun = iend - anchor; + if ((LZ4_COMPRESSMIN>0) && (((op - (BYTE*)dest) + lastRun + 1 + ((lastRun-15)/255)) > isize - LZ4_COMPRESSMIN)) return 0; + if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK< 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; } + else *op++ = (lastRun<>ML_BITS)) == RUN_MASK) { for (;(len=*ip++)==255;length+=255){} length += len; } + + // copy literals + cpy = op+length; + if unlikely(cpy>oend-COPYLENGTH) + { + if (cpy > oend) goto _output_error; // Error : request to write beyond destination buffer + memcpy(op, ip, length); + ip += length; + break; // Necessarily EOF + } + LZ4_WILDCOPY(ip, op, cpy); ip -= (op-cpy); op = cpy; + + // get offset + LZ4_READ_LITTLEENDIAN_16(ref,cpy,ip); ip+=2; + if (ref < (BYTE* const)dest) goto _output_error; // Error : offset create reference outside destination buffer + + // get matchlength + if ((length=(token&ML_MASK)) == ML_MASK) { for (;*ip==255;length+=255) {ip++;} length += *ip++; } + + // copy repeated sequence + if unlikely(op-refoend-COPYLENGTH) + { + if (cpy > oend) goto _output_error; // Error : request to write beyond destination buffer + LZ4_SECURECOPY(ref, op, (oend-COPYLENGTH)); + while(op>ML_BITS)) == RUN_MASK) { int s=255; while ((ipoend-COPYLENGTH) || (ip+length>iend-COPYLENGTH)) + { + if (cpy > oend) goto _output_error; // Error : request to write beyond destination buffer + if (ip+length > iend) goto _output_error; // Error : request to read beyond source buffer + memcpy(op, ip, length); + op += length; + ip += length; + if (ipoend-COPYLENGTH) + { + if (cpy > oend) goto _output_error; // Error : request to write outside of destination buffer + LZ4_SECURECOPY(ref, op, (oend-COPYLENGTH)); + while(op +#include + +namespace sofa { +namespace pbrpc { + +MockTestHelper::MockTestHelper() {} +MockTestHelper::~MockTestHelper() {} + +MockTestHelper* MockTestHelper::GlobalInstance() +{ + static MockTestHelperImpl s_mock_channel; + return &s_mock_channel; +} + +bool g_enable_mock = false; + +void enable_mock() +{ + MockTestHelper::GlobalInstance(); + g_enable_mock = true; +} + +void disable_mock() +{ + g_enable_mock = false; +} + +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/mock_test_helper.h b/src/sofa/pbrpc/mock_test_helper.h new file mode 100644 index 0000000..7a8d5f2 --- /dev/null +++ b/src/sofa/pbrpc/mock_test_helper.h @@ -0,0 +1,93 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_MOCK_TEST_HELPER_H_ +#define _SOFA_PBRPC_MOCK_TEST_HELPER_H_ + +#include +#include + +#include +#include + +namespace sofa { +namespace pbrpc { + +// All mock method implements should use this function signature. +typedef ExtClosure MockMethodHookFunction; + +// Mock test helper, it manages all mock functions. +class MockTestHelper +{ +public: + // Get the singleton instance. + static MockTestHelper* GlobalInstance(); + + virtual ~MockTestHelper(); + + // Register a mock method implement, which will be mapped to the "method_name". + // + // The "method_name" should be full name of method. + // The "mock_method" should be a permanenet closure, ownership of which is always take by user. + // + // If mock method already exist, the old one will be replaced. + virtual void RegisterMockMethod(const std::string& method_name, + MockMethodHookFunction* mock_method) = 0; + + // Clear all the registered mock method mapping. + virtual void ClearMockMethod() = 0; + + // Get the mock method mapped to the "method_name". Returns NULL if not registered. + virtual MockMethodHookFunction* GetMockMethod(const std::string& method_name) const = 0; + +protected: + MockTestHelper(); + +private: + SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(MockTestHelper); +}; + +extern bool g_enable_mock; +extern void enable_mock(); +extern void disable_mock(); + +} // namespace pbrpc +} // namespace sofa + +// Enable or disable the mock feature. Default disabled. +// The mock channel and mock methods will take effect iff mock enabled. +#define SOFA_PBRPC_ENABLE_MOCK() ::sofa::pbrpc::enable_mock() +#define SOFA_PBRPC_DISABLE_MOCK() ::sofa::pbrpc::disable_mock() + +// If you create a channel with address prefix of SOFA_PBRPC_MOCK_CHANNEL_ADDRESS_PREFIX, then the +// channel is a mock channel. The mock channel will not create real socket connection, but +// just uses mock methods. +#define SOFA_PBRPC_MOCK_CHANNEL_ADDRESS_PREFIX "/mock/" + +// Register a mock method implement. If mock enabled, all channels will prefer to call mock +// method first. If the corresponding mock method is not registered, then call the real method. +// +// "method_name" is the full name of the method to be mocked, should be a c-style string. +// "mock_method" is the mock method hook function, should be type of "MockMethodHookFunction*". +// +// For example: +// MockMethodHookFunction* mock_method = sofa::pbrpc::NewPermanentExtClosure(&MockEcho); +// SOFA_PBRPC_REGISTER_MOCK_METHOD("sofa.pbrpc.test.EchoServer.Echo", mock_method); +#define SOFA_PBRPC_REGISTER_MOCK_METHOD(method_name, mock_method) \ + ::sofa::pbrpc::MockTestHelper::GlobalInstance()->RegisterMockMethod(method_name, (mock_method)) + +// Clear all registered mock methods. This will not delete the cleared hook functions, which +// are take ownership by user. +#define SOFA_PBRPC_CLEAR_MOCK_METHOD() \ + ::sofa::pbrpc::MockTestHelper::GlobalInstance()->ClearMockMethod() + +#endif // _SOFA_PBRPC_MOCK_TEST_HELPER_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/mock_test_helper_impl.h b/src/sofa/pbrpc/mock_test_helper_impl.h new file mode 100644 index 0000000..40c8e6d --- /dev/null +++ b/src/sofa/pbrpc/mock_test_helper_impl.h @@ -0,0 +1,54 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_MOCK_TEST_HELPER_IMPL_H_ +#define _SOFA_PBRPC_MOCK_TEST_HELPER_IMPL_H_ + +#include + +#include +#include + +namespace sofa { +namespace pbrpc { + +class MockTestHelperImpl : public MockTestHelper +{ +public: + MockTestHelperImpl() {} + virtual ~MockTestHelperImpl() {} + + virtual void RegisterMockMethod(const std::string& method_name, + MockMethodHookFunction* mock_method) + { + ScopedLocker _(_lock); + _methods[method_name] = mock_method; + } + + virtual void ClearMockMethod() + { + ScopedLocker _(_lock); + _methods.clear(); + } + + virtual MockMethodHookFunction* GetMockMethod(const std::string& method_name) const + { + ScopedLocker _(_lock); + std::map::const_iterator it = _methods.find(method_name); + return it == _methods.end() ? NULL : it->second; + } + +private: + mutable FastLock _lock; + std::map _methods; +}; + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_MOCK_TEST_HELPER_IMPL_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/murmurhash.h b/src/sofa/pbrpc/murmurhash.h new file mode 100644 index 0000000..c3f32b6 --- /dev/null +++ b/src/sofa/pbrpc/murmurhash.h @@ -0,0 +1,75 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBPRC_MURMUR_HASH_H_ +#define _SOFA_PBPRC_MURMUR_HASH_H_ + +#include + +namespace sofa { +namespace pbrpc { + +inline uint64_t murmurhash(const void * key, int len) +{ + const uint64_t m = 0xc6a4a7935bd1e995; + const int r = 47; + uint64_t h = 0x5bd1e995; + + const uint64_t * data = (const uint64_t *)key; + const uint64_t * end = data + (len/8); + + while(data != end) { + uint64_t k = *data++; + + k *= m; + k ^= k >> r; + k *= m; + + h ^= k; + h *= m; + } + + const unsigned char * data2 = (const unsigned char*)data; + + switch(len & 7) { + case 7: + h ^= uint64_t(data2[6]) << 48; + case 6: + h ^= uint64_t(data2[5]) << 40; + case 5: + h ^= uint64_t(data2[4]) << 32; + case 4: + h ^= uint64_t(data2[3]) << 24; + case 3: + h ^= uint64_t(data2[2]) << 16; + case 2: + h ^= uint64_t(data2[1]) << 8; + case 1: + h ^= uint64_t(data2[0]); + h *= m; + break; + default: + break; + }; + + h ^= h >> r; + h *= m; + h ^= h >> r; + + return h; +} + +inline uint64_t murmurhash(const char* str) +{ + return murmurhash((const void*)str, strlen(str)); +} + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBPRC_MURMUR_HASH_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/mutex_lock.h b/src/sofa/pbrpc/mutex_lock.h new file mode 100644 index 0000000..d9c3ab7 --- /dev/null +++ b/src/sofa/pbrpc/mutex_lock.h @@ -0,0 +1,45 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_MUTEX_LOCK_H_ +#define _SOFA_PBRPC_MUTEX_LOCK_H_ + +#include + +namespace sofa { +namespace pbrpc { +class ConditionVariable; + +class MutexLock +{ +public: + MutexLock() + { + pthread_mutex_init(&_lock, NULL); + } + ~MutexLock() + { + pthread_mutex_destroy(&_lock); + } + void lock() + { + pthread_mutex_lock(&_lock); + } + void unlock() + { + pthread_mutex_unlock(&_lock); + } +private: + friend class ConditionVariable; + pthread_mutex_t _lock; +}; + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_MUTEX_LOCK_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/pbrpc.h b/src/sofa/pbrpc/pbrpc.h new file mode 100644 index 0000000..dfca963 --- /dev/null +++ b/src/sofa/pbrpc/pbrpc.h @@ -0,0 +1,29 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_PBRPC_H_ +#define _SOFA_PBRPC_PBRPC_H_ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // _SOFA_PBRPC_PBRPC_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/ptime.h b/src/sofa/pbrpc/ptime.h new file mode 100644 index 0000000..08e8e1b --- /dev/null +++ b/src/sofa/pbrpc/ptime.h @@ -0,0 +1,76 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_PTIME_H_ +#define _SOFA_PBRPC_PTIME_H_ + +#include // for snprintf() + +#include + +namespace sofa { +namespace pbrpc { + +typedef boost::posix_time::ptime PTime; +typedef boost::posix_time::time_duration TimeDuration; + +inline PTime ptime_now() +{ + return boost::posix_time::microsec_clock::universal_time(); +} + +inline PTime ptime_infin() +{ + return boost::posix_time::ptime(boost::posix_time::pos_infin); +} + +inline std::string ptime_to_string(const PTime& t) +{ + PTime::date_type date = t.date(); + TimeDuration tod = t.time_of_day(); + char buf[100]; + snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d.%06ld", + (int)date.year(), + (int)date.month(), + (int)date.day(), + tod.hours(), + tod.minutes(), + tod.seconds(), + tod.fractional_seconds()); + return buf; +} + +inline TimeDuration time_duration_hours(int64_t n) +{ + return boost::posix_time::hours(static_cast(n)); +} + +inline TimeDuration time_duration_minutes(int64_t n) +{ + return boost::posix_time::minutes(static_cast(n)); +} + +inline TimeDuration time_duration_seconds(int64_t n) +{ + return boost::posix_time::seconds(static_cast(n)); +} + +inline TimeDuration time_duration_milliseconds(int64_t n) +{ + return boost::posix_time::milliseconds(static_cast(n)); +} + +inline TimeDuration time_duration_microseconds(int64_t n) +{ + return boost::posix_time::microseconds(static_cast(n)); +} + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_PTIME_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_byte_stream.h b/src/sofa/pbrpc/rpc_byte_stream.h new file mode 100644 index 0000000..35c2307 --- /dev/null +++ b/src/sofa/pbrpc/rpc_byte_stream.h @@ -0,0 +1,315 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_RPC_BYTE_STREAM_H_ +#define _SOFA_PBRPC_RPC_BYTE_STREAM_H_ + +#include // for snprintf() +#include // for memset() + +#include +#include + +namespace sofa { +namespace pbrpc { + +using boost::asio::ip::tcp; + +class RpcByteStream : public sofa::pbrpc::enable_shared_from_this +{ +public: + RpcByteStream(IOService& io_service, const RpcEndpoint& endpoint) + : _io_service(io_service) + , _remote_endpoint(endpoint) + , _ticks(0) + , _last_rw_ticks(0) + , _socket(io_service) + , _status(STATUS_INIT) + { + SOFA_PBRPC_INC_RESOURCE_COUNTER(RpcByteStream); + memset(_error_message, 0, sizeof(_error_message)); + } + + virtual ~RpcByteStream() + { + SOFA_PBRPC_FUNCTION_TRACE; + close("stream destructed"); + boost::system::error_code ec; + _socket.close(ec); + SOFA_PBRPC_DEC_RESOURCE_COUNTER(RpcByteStream); + } + + // Close the channel. + void close(const std::string& reason) + { + // should run for only once + if (atomic_swap(&_status, (int)STATUS_CLOSED) != STATUS_CLOSED) + { + snprintf(_error_message, sizeof(_error_message), "%s", reason.c_str()); + boost::system::error_code ec; + _socket.shutdown(tcp::socket::shutdown_both, ec); + on_closed(); + if (_remote_endpoint != RpcEndpoint()) + { +#if defined( LOG ) + LOG(INFO) << "close(): connection closed: " + << RpcEndpointToString(_remote_endpoint) + << ": " << _error_message; +#else + SLOG(INFO, "close(): connection closed: %s: %s", + RpcEndpointToString(_remote_endpoint).c_str(), _error_message); +#endif + } + } + } + + // Connect the channel. Used by client. + void async_connect() + { + SOFA_PBRPC_FUNCTION_TRACE; + + _last_rw_ticks = _ticks; + + _status = STATUS_CONNECTING; + _socket.async_connect(_remote_endpoint, + boost::bind(&RpcByteStream::on_connect, shared_from_this(), _1)); + } + + // Set socket connected. Used by server. + // + // Precondition: + // * the "socket" is opened. + void set_socket_connected() + { + SOFA_PBRPC_FUNCTION_TRACE; + + _last_rw_ticks = _ticks; + + boost::system::error_code ec; + _local_endpoint = _socket.local_endpoint(ec); + if (ec) + { +#if defined( LOG ) + LOG(ERROR) << "set_socket_connected(): get local endpoint failed: " + << ec.message(); +#else + SLOG(ERROR, "set_socket_connected(): get local endpoint failed: %s", + ec.message().c_str()); +#endif + close("init stream failed: " + ec.message()); + return; + } + _remote_endpoint = _socket.remote_endpoint(ec); + if (ec) + { +#if defined( LOG ) + LOG(ERROR) << "set_socket_connected(): get remote endpoint failed: " + << ec.message(); +#else + SLOG(ERROR, "set_socket_connected(): get remote endpoint failed: %s", + ec.message().c_str()); +#endif + close("init stream failed: " + ec.message()); + return; + } + + if (!on_connected()) + { +#if defined( LOG ) + LOG(ERROR) << "set_socket_connected(): call on_connected() failed"; +#else + SLOG(ERROR, "set_socket_connected(): call on_connected() failed"); +#endif + close("init stream failed: call on_connected() failed"); + return; + } + + _status = STATUS_CONNECTED; + trigger_receive(); + trigger_send(); + } + + // Get the socket. + tcp::socket& socket() + { + return _socket; + } + + // Get the local endpoint. + const RpcEndpoint& local_endpoint() const + { + return _local_endpoint; + } + + // Get the remote endpoint. + const RpcEndpoint& remote_endpoint() const + { + return _remote_endpoint; + } + + // Check if the channel is connecting. + bool is_connecting() const + { + return _status == STATUS_CONNECTING; + } + + // Check if the channel is connected. + bool is_connected() const + { + return _status == STATUS_CONNECTED; + } + + // Check if the channel is closed. + bool is_closed() const + { + return _status == STATUS_CLOSED; + } + + // Reset current time ticks. + void reset_ticks(int64 ticks) + { + _ticks = ticks; + } + + // Get the last time ticks for read or write. + int64 last_rw_ticks() const + { + return _last_rw_ticks; + } + + // Trigger receiving operator. + // @return true if suceessfully triggered + virtual bool trigger_receive() = 0; + + // Trigger sending operator. + // @return true if suceessfully triggered + virtual bool trigger_send() = 0; + +protected: + // Async read some data from the stream. + void async_read_some(char* data, size_t size) + { + SOFA_PBRPC_FUNCTION_TRACE; + + _socket.async_read_some(boost::asio::buffer(data, size), + boost::bind(&RpcByteStream::on_read_some, + shared_from_this(), _1, _2)); + } + + // Async write some data to the stream. + void async_write_some(const char* data, size_t size) + { + SOFA_PBRPC_FUNCTION_TRACE; + + _socket.async_write_some(boost::asio::buffer(data, size), + boost::bind(&RpcByteStream::on_write_some, + shared_from_this(), _1, _2)); + } + + // Hook function when connected. + // @return false if some error occured. + virtual bool on_connected() = 0; + + // Hook function when closed. + virtual void on_closed() = 0; + + // Callback of "async_read_some()". + virtual void on_read_some( + const boost::system::error_code& error, + std::size_t bytes_transferred) = 0; + + // Callback of "async_write_some()". + virtual void on_write_some( + const boost::system::error_code& error, + std::size_t bytes_transferred) = 0; + +private: + // Callback of "async_connect()". + void on_connect(const boost::system::error_code& error) + { + SOFA_PBRPC_FUNCTION_TRACE; + + if (error) + { + // TODO retry connect? +#if defined( LOG ) + LOG(ERROR) << "on_connect(): connect error: " + << RpcEndpointToString(_remote_endpoint) << ": " << error.message(); +#else + SLOG(ERROR, "on_connect(): connect error: %s: %s", + RpcEndpointToString(_remote_endpoint).c_str(), + error.message().c_str()); +#endif + + close("init stream failed: " + error.message()); + return; + } + + boost::system::error_code ec; + _local_endpoint = _socket.local_endpoint(ec); + if (ec) + { +#if defined( LOG ) + LOG(ERROR) << "on_connect(): get local endpoint failed: " + << ec.message(); +#else + SLOG(ERROR, "on_connect(): get local endpoint failed: %s", + ec.message().c_str()); +#endif + close("init stream failed: " + ec.message()); + return; + } + + if (!on_connected()) + { +#if defined( LOG ) + LOG(ERROR) << "on_connect(): call on_connected() failed"; +#else + SLOG(ERROR, "on_connect(): call on_connected() failed"); +#endif + close("init stream failed: call on_connected() failed"); + return; + } + +#if defined( LOG ) + LOG(INFO) << "on_connect(): connection established: " + << RpcEndpointToString(_remote_endpoint); +#else + SLOG(INFO, "on_connect(): connection established: %s", + RpcEndpointToString(_remote_endpoint).c_str()); +#endif + + _status = STATUS_CONNECTED; + trigger_receive(); + trigger_send(); + } + +protected: + IOService& _io_service; + RpcEndpoint _local_endpoint; + RpcEndpoint _remote_endpoint; + char _error_message[128]; + volatile int64 _ticks; + volatile int64 _last_rw_ticks; + +private: + tcp::socket _socket; + + enum { + STATUS_INIT = 0, + STATUS_CONNECTING = 1, + STATUS_CONNECTED = 2, + STATUS_CLOSED = 3, + }; + volatile int _status; +}; // class RpcByteStream + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_RPC_BYTE_STREAM_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_channel.cc b/src/sofa/pbrpc/rpc_channel.cc new file mode 100644 index 0000000..770bf14 --- /dev/null +++ b/src/sofa/pbrpc/rpc_channel.cc @@ -0,0 +1,54 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include + +#include +#include +#include + +namespace sofa { +namespace pbrpc { + +RpcChannel::RpcChannel(RpcClient* rpc_client, + const std::string& server_address, + const RpcChannelOptions& options) + : _impl(new RpcChannelImpl(rpc_client->impl(), server_address, options)) +{ +} + +RpcChannel::RpcChannel(RpcClient* rpc_client, + const std::string& server_ip, + uint32 server_port, + const RpcChannelOptions& options) +{ + std::ostringstream os; + os << server_ip << ":" << server_port; + _impl.reset(new RpcChannelImpl(rpc_client->impl(), os.str(), options)); +} + +RpcChannel::~RpcChannel() +{ +} + +bool RpcChannel::IsAddressValid() +{ + return _impl->IsAddressValid(); +} + +void RpcChannel::CallMethod(const ::google::protobuf::MethodDescriptor* method, + ::google::protobuf::RpcController* controller, + const ::google::protobuf::Message* request, + ::google::protobuf::Message* response, + ::google::protobuf::Closure* done) +{ + _impl->CallMethod(method, controller, request, response, done); +} + +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_channel.h b/src/sofa/pbrpc/rpc_channel.h new file mode 100644 index 0000000..efbaec1 --- /dev/null +++ b/src/sofa/pbrpc/rpc_channel.h @@ -0,0 +1,77 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_RPC_CHANNEL_H_ +#define _SOFA_PBRPC_RPC_CHANNEL_H_ + +#include + +#include + +namespace sofa { +namespace pbrpc { + +// Defined in other files. +class RpcClient; +class RpcChannelImpl; + +struct RpcChannelOptions { + // Connect timeout (in seconds). + // If a request can't get an healthy connection after a connect_timeout + // milliseconds, it will fail and return to the caller. + // + // Not supported now. + int64 connect_timeout; + + RpcChannelOptions() + : connect_timeout(10) + {} +}; + +class RpcChannel : public google::protobuf::RpcChannel +{ +public: + // The "server_address" should be in format of "ip:port". + RpcChannel(RpcClient* rpc_client, + const std::string& server_address, + const RpcChannelOptions& options = RpcChannelOptions()); + RpcChannel(RpcClient* rpc_client, + const std::string& server_ip, + uint32 server_port, + const RpcChannelOptions& options = RpcChannelOptions()); + virtual ~RpcChannel(); + + // Check the channel's address is valid. If not valid, the following invoke + // of "CallMethod()" will return RPC_ERROR_RESOLVE_ADDRESS. + bool IsAddressValid(); + + // Implements the google::protobuf::RpcChannel interface. If the + // "done" is NULL, it's a synchronous call, or it's asynchronous and + // uses the callback to inform the completion (or failure). + virtual void CallMethod(const ::google::protobuf::MethodDescriptor* method, + ::google::protobuf::RpcController* controller, + const ::google::protobuf::Message* request, + ::google::protobuf::Message* response, + ::google::protobuf::Closure* done); + +public: + const sofa::pbrpc::shared_ptr& impl() const + { + return _impl; + } + +private: + sofa::pbrpc::shared_ptr _impl; + + SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(RpcChannel); +}; // class RpcChannel + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_RPC_CHANNEL_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_channel_impl.cc b/src/sofa/pbrpc/rpc_channel_impl.cc new file mode 100644 index 0000000..cadb7e5 --- /dev/null +++ b/src/sofa/pbrpc/rpc_channel_impl.cc @@ -0,0 +1,185 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include +#include +#include + +namespace sofa { +namespace pbrpc { + +RpcChannelImpl::RpcChannelImpl(const RpcClientImplPtr& rpc_client_impl, + const std::string& server_address, + const RpcChannelOptions& options) + : _client_impl(rpc_client_impl) + , _server_address(server_address) + , _options(options) + , _is_mock(false) + , _resolve_address_succeed(false) +{ + if (g_enable_mock && _server_address.find(SOFA_PBRPC_MOCK_CHANNEL_ADDRESS_PREFIX) == 0) + { +#if defined( LOG ) + LOG(INFO) << "RpcChannelImpl(): use mock channel"; +#else + SLOG(INFO, "RpcChannelImpl(): use mock channel"); +#endif + _is_mock = true; + return; + } + + if (_client_impl->ResolveAddress(_server_address, &_remote_endpoint)) + { +#if defined( LOG ) + LOG(INFO) << "RpcChannelImpl(): resolve address succeed: " << _server_address + << " [" << RpcEndpointToString(_remote_endpoint) << "]"; +#else + SLOG(INFO, "RpcChannelImpl(): resolve address succeed: %s [%s]", + _server_address.c_str(), RpcEndpointToString(_remote_endpoint).c_str()); +#endif + _resolve_address_succeed = true; + } + else + { +#if defined( LOG ) + LOG(ERROR) << "RpcChannelImpl(): resolve address failed: " << _server_address; +#else + SLOG(ERROR, "RpcChannelImpl(): resolve address failed: %s", + _server_address.c_str()); +#endif + } +} + +RpcChannelImpl::~RpcChannelImpl() +{ +} + +bool RpcChannelImpl::IsAddressValid() +{ + return _resolve_address_succeed; +} + +void RpcChannelImpl::CallMethod(const ::google::protobuf::MethodDescriptor* method, + ::google::protobuf::RpcController* controller, + const ::google::protobuf::Message* request, + ::google::protobuf::Message* response, + ::google::protobuf::Closure* done) +{ + SCHECK(method != NULL); + SCHECK(controller != NULL); + SCHECK(request != NULL); + SCHECK(response != NULL); + + // prepare controller + RpcController* sofa_controller = dynamic_cast(controller); + SCHECK(sofa_controller != NULL); // should pass sofa::pbrpc::RpcController to CallMethod + RpcControllerImplPtr cntl = sofa_controller->impl(); + cntl->PushDoneCallback(boost::bind(&RpcChannelImpl::DoneCallback, shared_from_this(), done, _1)); + cntl->FillFromMethodDescriptor(method); + if (done == NULL) + { + cntl->SetSync(); // null done means sync call + cntl->SetWaitEvent(WaitEventPtr(new WaitEvent())); + } + + // check if mocked + if (g_enable_mock && _is_mock) + { + MockMethodHookFunction* mock_closure = + MockTestHelper::GlobalInstance()->GetMockMethod(method->full_name()); + if (mock_closure) + { + // mock method registered +#if defined( LOG ) + LOG(INFO) << "CallMethod(): mock method [" + << method->full_name() << "] called"; +#else + SLOG(INFO, "CallMethod(): mock method [%s] called", + method->full_name().c_str()); +#endif + ::google::protobuf::Closure* mock_done = + NewClosure(&RpcChannelImpl::MockDoneCallback, cntl, request, response); + mock_closure->Run(controller, request, response, mock_done); + } + else + { + // mock method not registered, but it is in mock channel +#if defined( LOG ) + LOG(ERROR) << "CallMethod(): mock method [" + << method->full_name() << "] not registered" + << ", but used in mock channel"; +#else + SLOG(ERROR, "CallMethod(): mock method [%s] not registered" + ", but used in mock channel", method->full_name().c_str()); +#endif + cntl->Done(RPC_ERROR_FOUND_METHOD, "mock method not registered: " + + method->full_name()); + } + WaitDone(cntl); + return; + } + + if (!_resolve_address_succeed) + { + // TODO resolve address failed, retry resolve? +#if defined( LOG ) + LOG(ERROR) << "CallMethod(): resolve address failed: " << _server_address; +#else + SLOG(ERROR, "CallMethod(): resolve address failed: %s", _server_address.c_str()); +#endif + cntl->Done(RPC_ERROR_RESOLVE_ADDRESS, _server_address); + WaitDone(cntl); + return; + } + + // ready, go ahead to do real call + cntl->SetRemoteEndpoint(_remote_endpoint); + cntl->StartTimer(); + _client_impl->CallMethod(request, response, cntl); + WaitDone(cntl); +} + +void RpcChannelImpl::WaitDone(const RpcControllerImplPtr& cntl) +{ + // if sync, wait for callback done + if (cntl->IsSync()) + { + cntl->WaitEvent()->Wait(); + SCHECK(cntl->IsDone()); + } +} + +void RpcChannelImpl::DoneCallback(google::protobuf::Closure* done, + const RpcControllerImplPtr& cntl) +{ + if (cntl->IsSync()) + { + SCHECK(done == NULL); + SCHECK(cntl->WaitEvent()); + cntl->WaitEvent()->Signal(); + } + else + { + SCHECK(done != NULL); + _client_impl->GetCallbackThreadGroup()->post(done); + } +} + +void RpcChannelImpl::MockDoneCallback(RpcControllerImplPtr cntl, + const ::google::protobuf::Message* request, + ::google::protobuf::Message* /*response*/) +{ + if (!cntl->Failed()) + { + cntl->NotifyRequestSent(RpcEndpoint(), request->ByteSize()); + } + cntl->Done(cntl->ErrorCode(), cntl->Reason()); +} + +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_channel_impl.h b/src/sofa/pbrpc/rpc_channel_impl.h new file mode 100644 index 0000000..9c4bcd1 --- /dev/null +++ b/src/sofa/pbrpc/rpc_channel_impl.h @@ -0,0 +1,63 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_RPC_CHANNEL_IMPL_H_ +#define _SOFA_PBRPC_RPC_CHANNEL_IMPL_H_ + +#include +#include +#include +#include +#include + +namespace sofa { +namespace pbrpc { + +class RpcChannelImpl : public sofa::pbrpc::enable_shared_from_this +{ +public: + RpcChannelImpl(const RpcClientImplPtr& rpc_client_impl, + const std::string& server_address, + const RpcChannelOptions& options); + + virtual ~RpcChannelImpl(); + + bool IsAddressValid(); + + void CallMethod(const ::google::protobuf::MethodDescriptor* method, + ::google::protobuf::RpcController* controller, + const ::google::protobuf::Message* request, + ::google::protobuf::Message* response, + ::google::protobuf::Closure* done); + +private: + static void WaitDone(const RpcControllerImplPtr& cntl); + + void DoneCallback(google::protobuf::Closure* done, + const RpcControllerImplPtr& cntl); + + static void MockDoneCallback(RpcControllerImplPtr cntl, + const ::google::protobuf::Message* request, + ::google::protobuf::Message* response); + +private: + RpcClientImplPtr _client_impl; + std::string _server_address; + RpcChannelOptions _options; + + bool _is_mock; + bool _resolve_address_succeed; + RpcEndpoint _remote_endpoint; + + SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(RpcChannelImpl); +}; // class RpcChannelImpl + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_RPC_CHANNEL_IMPL_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_client.cc b/src/sofa/pbrpc/rpc_client.cc new file mode 100644 index 0000000..6139525 --- /dev/null +++ b/src/sofa/pbrpc/rpc_client.cc @@ -0,0 +1,47 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include +#include + +namespace sofa { +namespace pbrpc { + +RpcClient::RpcClient(const RpcClientOptions& options) + : _impl(new RpcClientImpl(options)) +{ + _impl->Start(); +} + +RpcClient::~RpcClient() +{ + Shutdown(); +} + +RpcClientOptions RpcClient::GetOptions() +{ + return _impl->GetOptions(); +} + +void RpcClient::ResetOptions(const RpcClientOptions& options) +{ + _impl->ResetOptions(options); +} + +int RpcClient::ConnectionCount() +{ + return _impl->ConnectionCount(); +} + +void RpcClient::Shutdown() +{ + _impl->Stop(); +} + +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_client.h b/src/sofa/pbrpc/rpc_client.h new file mode 100644 index 0000000..4e53506 --- /dev/null +++ b/src/sofa/pbrpc/rpc_client.h @@ -0,0 +1,96 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_RPC_CLIENT_H_ +#define _SOFA_PBRPC_RPC_CLIENT_H_ + +#include + +namespace sofa { +namespace pbrpc { + +// Defined in other files. +class RpcClientImpl; + +struct RpcClientOptions { + int work_thread_num; // num of threads used for network handing, default 4. + int callback_thread_num; // num of threads used for async callback, default 4. + + int keep_alive_time; // keep alive time of idle connections. + // idle connections will be closed if no read/write for this time. + // in seconds, should >= -1, -1 means for ever, default 65. + + int max_pending_buffer_size; // max buffer size of the pending send queue for each connection. + // in MB, should >= 0, 0 means no buffer, default 2. + + // Network throughput limit. + // The network bandwidth is shared by all connections: + // * busy connections get more bandwidth. + // * the total bandwidth of all connections will not exceed the limit. + int max_throughput_in; // max network in throughput for all connections. + // in MB/s, should >= -1, -1 means no limit, default -1. + int max_throughput_out; // max network out throughput for all connections. + // in MB/s, should >= -1, -1 means no limit, default -1. + + RpcClientOptions() + : work_thread_num(4) + , callback_thread_num(4) + , keep_alive_time(65) + , max_pending_buffer_size(2) + , max_throughput_in(-1) + , max_throughput_out(-1) + {} +}; + +class RpcClient +{ +public: + explicit RpcClient(const RpcClientOptions& options = RpcClientOptions()); + virtual ~RpcClient(); + + // Get the current rpc client options. + RpcClientOptions GetOptions(); + + // Reset the rpc client options. + // + // Current only these options can be reset (others will be ignored): + // * max_pending_buffer_size : will take effective immediately. + // * max_throughput_in : will take effective from the next time slice (0.1s). + // * max_throughput_out : will take effective from the next time slice (0.1s). + // + // Though you want to reset only part of these options, the other options also + // need to be set. Maybe you can reset by this way: + // RpcClientOptions options = rpc_client->GetOptions(); + // options.max_throughput_in = new_max_throughput_in; // reset some options + // rpc_client->ResetOptions(options); + // + // The old and new value of reset options will be print to INFO log. + void ResetOptions(const RpcClientOptions& options); + + // Get the count of current alive connections. + int ConnectionCount(); + + // Shutdown the rpc client. + void Shutdown(); + +public: + const sofa::pbrpc::shared_ptr& impl() const + { + return _impl; + } + +private: + sofa::pbrpc::shared_ptr _impl; + + SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(RpcClient); +}; // class RpcClient + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_RPC_CLIENT_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_client_impl.cc b/src/sofa/pbrpc/rpc_client_impl.cc new file mode 100644 index 0000000..1010b61 --- /dev/null +++ b/src/sofa/pbrpc/rpc_client_impl.cc @@ -0,0 +1,571 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include +#include + +#include +#include +#include +#include + +namespace sofa { +namespace pbrpc { + +RpcClientImpl::RpcClientImpl(const RpcClientOptions& options) + : _options(options) + , _is_running(false) + , _next_request_id(0) + , _epoch_time(ptime_now()) + , _ticks_per_second(time_duration_seconds(1).ticks()) + , _last_maintain_ticks(0) + , _last_print_connection_ticks(0) + , _live_stream_count(0) +{ + _slice_count = std::max(1, 1000 / MAINTAIN_INTERVAL_IN_MS); + _slice_quota_in = _options.max_throughput_in == -1 ? + -1 : std::max(0L, _options.max_throughput_in * 1024L * 1024L) / _slice_count; + _slice_quota_out = _options.max_throughput_out == -1 ? + -1 : std::max(0L, _options.max_throughput_out * 1024L * 1024L) / _slice_count; + _max_pending_buffer_size = + std::max(0L, _options.max_pending_buffer_size * 1024L * 1024L); + _keep_alive_ticks = _options.keep_alive_time == -1 ? + -1 : std::max(1, _options.keep_alive_time) * _ticks_per_second; + _print_connection_interval_ticks = _ticks_per_second * 60; + +#if defined( LOG ) + LOG(INFO) << "RpcClientImpl(): quota_in=" + << (_slice_quota_in == -1 ? -1 : _slice_quota_in * _slice_count / (1024L * 1024L)) + << "MB/s, quota_out=" + << (_slice_quota_out == -1 ? -1 : _slice_quota_out * _slice_count / (1024L * 1024L)) + << "MB/s, max_pending_buffer_size=" + << (_max_pending_buffer_size / (1024L * 1024L)) + << "MB, keep_alive_time=" + << (_keep_alive_ticks == -1 ? -1 : _keep_alive_ticks / _ticks_per_second) + << "seconds"; +#else + SLOG(INFO, "RpcClientImpl(): quota_in=%lldMB/s, quota_out=%lldMB/s" + ", max_pending_buffer_size=%lldMB, keep_alive_time=%lldseconds", + _slice_quota_in == -1 ? -1 : _slice_quota_in * _slice_count / (1024L * 1024L), + _slice_quota_out == -1 ? -1 : _slice_quota_out * _slice_count / (1024L * 1024L), + _max_pending_buffer_size / (1024L * 1024L), + _keep_alive_ticks == -1 ? -1 : _keep_alive_ticks / _ticks_per_second); +#endif +} + +RpcClientImpl::~RpcClientImpl() +{ + SOFA_PBRPC_FUNCTION_TRACE; + Stop(); +} + +void RpcClientImpl::Start() +{ + ScopedLocker _(_start_stop_lock); + if (_is_running) return; + + _flow_controller.reset(new FlowController( + _slice_quota_in == -1, _slice_quota_in, + _slice_quota_out == -1, _slice_quota_out)); + + _maintain_thread_group.reset(new ThreadGroupImpl( + 2, "sofa_pbrpc_client_maintain_thread_group")); + _maintain_thread_group->start(); + + _callback_thread_group.reset(new ThreadGroupImpl( + _options.callback_thread_num, "sofa_pbrpc_client_callback_thread_group")); + _callback_thread_group->start(); + + _work_thread_group.reset(new ThreadGroupImpl( + _options.work_thread_num, "sofa_pbrpc_client_work_thread_group")); + _work_thread_group->start(); + + _timer_worker.reset(new TimerWorker(_maintain_thread_group->io_service())); + _timer_worker->set_time_duration(time_duration_milliseconds(MAINTAIN_INTERVAL_IN_MS)); + _timer_worker->set_work_routine(boost::bind( + &RpcClientImpl::TimerMaintain, shared_from_this(), _1)); + _timer_worker->start(); + + _timeout_manager.reset(new RpcTimeoutManager(_maintain_thread_group->io_service())); + _timeout_manager->start(); + + _is_running = true; + +#if defined( LOG ) + LOG(INFO) << "Start(): rpc client started"; +#else + SLOG(INFO, "Start(): rpc client started"); +#endif +} + +void RpcClientImpl::Stop() +{ + ScopedLocker _(_start_stop_lock); + if (!_is_running) return; + _is_running = false; + + _timeout_manager->stop(); + _timer_worker->stop(); + StopStreams(); + _work_thread_group->stop(); + + _timeout_manager.reset(); + _timer_worker.reset(); + ClearStreams(); + _callback_thread_group->stop(); + _maintain_thread_group->stop(); + + _work_thread_group.reset(); + _callback_thread_group.reset(); + _maintain_thread_group.reset(); + _flow_controller.reset(); + +#if defined( LOG ) + LOG(INFO) << "Stop(): rpc client stopped"; +#else + SLOG(INFO, "Stop(): rpc client stopped"); +#endif +} + +RpcClientOptions RpcClientImpl::GetOptions() +{ + return _options; +} + +void RpcClientImpl::ResetOptions(const RpcClientOptions& options) +{ + int64 old_slice_quota_in = _slice_quota_in; + int64 old_slice_quota_out = _slice_quota_out; + int64 old_max_pending_buffer_size = _max_pending_buffer_size; + int64 old_keep_alive_ticks = _keep_alive_ticks; + + _options.max_throughput_in = options.max_throughput_in; + _options.max_throughput_out = options.max_throughput_out; + _options.max_pending_buffer_size = options.max_pending_buffer_size; + _options.keep_alive_time = options.keep_alive_time; + + _slice_quota_in = _options.max_throughput_in == -1 ? + -1 : std::max(0L, _options.max_throughput_in * 1024L * 1024L) / _slice_count; + _slice_quota_out = _options.max_throughput_out == -1 ? + -1 : std::max(0L, _options.max_throughput_out * 1024L * 1024L) / _slice_count; + _max_pending_buffer_size = + std::max(0L, options.max_pending_buffer_size * 1024L * 1024L); + _keep_alive_ticks = _options.keep_alive_time == -1 ? + -1 : std::max(1, _options.keep_alive_time) * _ticks_per_second; + + if (_max_pending_buffer_size != old_max_pending_buffer_size) + { + ScopedLocker _(_stream_map_lock); + for (StreamMap::iterator it = _stream_map.begin(); it != _stream_map.end(); ) + { + it->second->set_max_pending_buffer_size(_max_pending_buffer_size); + } + } + +#if defined( LOG ) + LOG(INFO) << "ResetOptions(): quota_in=" + << (_slice_quota_in == -1 ? -1 : _slice_quota_in * _slice_count / (1024L * 1024L)) + << "MB/s(old " + << (old_slice_quota_in == -1 ? -1 : old_slice_quota_in * _slice_count / (1024L * 1024L)) + << "MB/s), quota_out=" + << (_slice_quota_out == -1 ? -1 : _slice_quota_out * _slice_count / (1024L * 1024L)) + << "MB/s(old " + << (old_slice_quota_out == -1 ? -1 : old_slice_quota_out * _slice_count / (1024L * 1024L)) + << "MB/s), max_pending_buffer_size=" + << (_max_pending_buffer_size / (1024L * 1024L)) + << "MB(old " + << (old_max_pending_buffer_size / (1024L * 1024L)) + << "MB), keep_alive_time=" + << (_keep_alive_ticks == -1 ? -1 : _keep_alive_ticks / _ticks_per_second) + << "seconds(old " + << (old_keep_alive_ticks == -1 ? -1 : old_keep_alive_ticks / _ticks_per_second) + << "seconds)"; +#else + SLOG(INFO, "ResetOptions(): quota_in=%lldMB/s(old %lldMB/s)" + ", quota_out=%lldMB/s(old %lldMB/s)" + ", max_pending_buffer_size=%lldMB(old %lldMB)", + ", keep_alive_time=%lldseconds(old %lldseconds)", + _slice_quota_in == -1 ? -1 : _slice_quota_in * _slice_count / (1024L * 1024L), + old_slice_quota_in == -1 ? -1 : old_slice_quota_in * _slice_count / (1024L * 1024L), + _slice_quota_out == -1 ? -1 : _slice_quota_out * _slice_count / (1024L * 1024L), + old_slice_quota_out == -1 ? -1 : old_slice_quota_out * _slice_count / (1024L * 1024L), + _max_pending_buffer_size / (1024L * 1024L), + old_max_pending_buffer_size / (1024L * 1024L), + _keep_alive_ticks == -1 ? -1 : _keep_alive_ticks / _ticks_per_second, + old_keep_alive_ticks == -1 ? -1 : old_keep_alive_ticks / _ticks_per_second); +#endif +} + +int RpcClientImpl::ConnectionCount() +{ + return _live_stream_count; +} + +// Rpc call method to remote endpoint. +// +// The call can be done in following cases: +// * send failed +// * timeouted +// * received response +void RpcClientImpl::CallMethod(const google::protobuf::Message* request, + google::protobuf::Message* response, + const RpcControllerImplPtr& cntl) +{ + if (!_is_running) + { +#if defined( LOG ) + LOG(ERROR) << "CallMethod(): client not in running, ignore"; +#else + SLOG(ERROR, "CallMethod(): client not in running, ignore"); +#endif + cntl->Done(RPC_ERROR_NOT_IN_RUNNING, "client not in running, should start it first"); + return; + } + + // get the stream + RpcClientStreamPtr stream = FindOrCreateStream(cntl->RemoteEndpoint()); + if (!stream) + { +#if defined( LOG ) + LOG(ERROR) << "CallMethod(): create socket stream failed: " + << RpcEndpointToString(cntl->RemoteEndpoint()); +#else + SLOG(ERROR, "CallMethod(): create socket stream failed: %s", + RpcEndpointToString(cntl->RemoteEndpoint()).c_str()); +#endif + cntl->Done(RPC_ERROR_CREATE_STREAM, "create stream failed, maybe exceed connection limit"); + return; + } + cntl->SetRpcClientStream(stream); + + // check the pending buffer full + if (stream->pending_buffer_size() > stream->max_pending_buffer_size()) + { +#if defined( LOG ) +#else + SLOG(DEBUG, "CallMethod(): pending buffer full: %s", + RpcEndpointToString(cntl->RemoteEndpoint()).c_str()); +#endif + cntl->Done(RPC_ERROR_SEND_BUFFER_FULL, "pending buffer full"); + return; + } + + // generate sequence id + cntl->SetSequenceId(GenerateSequenceId()); + + // prepare request buffer + RpcMeta meta; + meta.set_type(RpcMeta::REQUEST); + meta.set_sequence_id(cntl->SequenceId()); + meta.set_method(cntl->MethodId()); + meta.set_compress_type(cntl->RequestCompressType()); + meta.set_expected_response_compress_type(cntl->ResponseCompressType()); + + RpcMessageHeader header; + int header_size = sizeof(header); + WriteBuffer write_buffer; + int64 header_pos = write_buffer.Reserve(header_size); + if (header_pos < 0) + { +#if defined( LOG ) + LOG(ERROR) << "CallMethod(): " << RpcEndpointToString(cntl->RemoteEndpoint()) + << ": reserve rpc message header failed"; +#else + SLOG(ERROR, "CallMethod(): %s: reserve rpc message header failed", + RpcEndpointToString(cntl->RemoteEndpoint()).c_str()); +#endif + cntl->Done(RPC_ERROR_SERIALIZE_REQUEST, "reserve rpc message header failed"); + return; + } + if (!meta.SerializeToZeroCopyStream(&write_buffer)) + { +#if defined( LOG ) + LOG(ERROR) << "CallMethod(): " << RpcEndpointToString(cntl->RemoteEndpoint()) + << ": serialize rpc meta failed"; +#else + SLOG(ERROR, "CallMethod(): %s: serialize rpc meta failed", + RpcEndpointToString(cntl->RemoteEndpoint()).c_str()); +#endif + cntl->Done(RPC_ERROR_SERIALIZE_REQUEST, "serialize rpc meta failed"); + return; + } + header.meta_size = static_cast(write_buffer.ByteCount() - header_pos - header_size); + bool serialize_request_return = false; + if (meta.compress_type() == CompressTypeNone) + { + serialize_request_return = request->SerializeToZeroCopyStream(&write_buffer); + } + else + { + ::sofa::pbrpc::scoped_ptr os( + get_compressed_output_stream(&write_buffer, meta.compress_type())); + serialize_request_return = request->SerializeToZeroCopyStream(os.get()); + os->Flush(); + } + if (!serialize_request_return) + { +#if defined( LOG ) + LOG(ERROR) << "CallMethod(): " << RpcEndpointToString(cntl->RemoteEndpoint()) + << ": serialize request message failed"; +#else + SLOG(ERROR, "CallMethod(): %s: serialize request message failed", + RpcEndpointToString(cntl->RemoteEndpoint()).c_str()); +#endif + cntl->Done(RPC_ERROR_SERIALIZE_REQUEST, "serialize request message failed"); + return; + } + header.data_size = write_buffer.ByteCount() - header_pos - header_size - header.meta_size; + header.message_size = header.meta_size + header.data_size; + write_buffer.SetData(header_pos, reinterpret_cast(&header), header_size); + + ReadBufferPtr read_buffer(new ReadBuffer()); + write_buffer.SwapOut(read_buffer.get()); + cntl->SetRequestBuffer(read_buffer); + + // push callback + cntl->PushDoneCallback(boost::bind(&RpcClientImpl::DoneCallback, shared_from_this(), response, _1)); + + // add to timeout manager if need + int64 timeout = cntl->Timeout(); + if (timeout > 0) + { + if (!_timeout_manager->add(cntl)) + { +#if defined( LOG ) + LOG(ERROR) << "CallMethod(): " << RpcEndpointToString(cntl->RemoteEndpoint()) + << ": add to timeout manager failed: timeout=" << timeout << "ms"; +#else + SLOG(ERROR, "CallMethod(): %s: add to timeout manager failed: timeout=%llsms", + RpcEndpointToString(cntl->RemoteEndpoint()).c_str(), timeout); +#endif + cntl->Done(RPC_ERROR_REQUEST_TIMEOUT, "add to timeout manager failed, maybe too short timeout"); + return; + } + } + + // call method + stream->call_method(cntl); +} + +const ThreadGroupImplPtr& RpcClientImpl::GetCallbackThreadGroup() const +{ + return _callback_thread_group; +} + +bool RpcClientImpl::ResolveAddress(const std::string& address, + RpcEndpoint* endpoint) +{ + return sofa::pbrpc::ResolveAddress(_work_thread_group->io_service(), address, endpoint); +} + +RpcClientStreamPtr RpcClientImpl::FindOrCreateStream( + const RpcEndpoint& remote_endpoint) +{ + RpcClientStreamPtr stream; + bool create = false; + { + ScopedLocker _(_stream_map_lock); + StreamMap::iterator find = _stream_map.find(remote_endpoint); + if (find != _stream_map.end() && !find->second->is_closed()) + { + stream = find->second; + } + else + { + stream.reset(new RpcClientStream(_work_thread_group->io_service(), remote_endpoint)); + stream->set_flow_controller(_flow_controller); + stream->set_max_pending_buffer_size(_max_pending_buffer_size); + stream->reset_ticks((ptime_now() - _epoch_time).ticks()); + + _stream_map[remote_endpoint] = stream; + create = true; + } + } + if (create) + { + stream->async_connect(); + } + return stream; +} + +void RpcClientImpl::StopStreams() +{ + ScopedLocker _(_stream_map_lock); + for (StreamMap::iterator it = _stream_map.begin(); + it != _stream_map.end(); ++it) + { + it->second->close("client stopped"); + } +} + +void RpcClientImpl::ClearStreams() +{ + ScopedLocker _(_stream_map_lock); + _stream_map.clear(); +} + +void RpcClientImpl::DoneCallback(google::protobuf::Message* response, + const RpcControllerImplPtr& cntl) +{ + // erase from RpcTimeoutManager + _timeout_manager->erase(cntl->TimeoutId()); + + // deserialize response + if (!cntl->Failed()) + { + SCHECK(response != NULL); + SCHECK(cntl->ResponseBuffer()); + ReadBufferPtr buffer = cntl->ResponseBuffer(); + CompressType compress_type = cntl->ResponseCompressType(); + bool parse_response_return = false; + if (compress_type == CompressTypeNone) + { + parse_response_return = response->ParseFromZeroCopyStream(buffer.get()); + } + else + { + ::sofa::pbrpc::scoped_ptr is( + get_compressed_input_stream(buffer.get(), compress_type)); + parse_response_return = response->ParseFromZeroCopyStream(is.get()); + } + if (!parse_response_return) + { +#if defined( LOG ) + LOG(ERROR) << "DoneCallback(): " << RpcEndpointToString(cntl->RemoteEndpoint()) + << ": parse response message pb failed"; +#else + SLOG(ERROR, "DoneCallback(): %s: parse response message pb failed", + RpcEndpointToString(cntl->RemoteEndpoint()).c_str()); +#endif + cntl->SetFailed(RPC_ERROR_PARSE_RESPONSE_MESSAGE, "parse response message pb failed"); + } + } +} + +void RpcClientImpl::TimerMaintain(const PTime& now) +{ + SOFA_PBRPC_FUNCTION_TRACE; + + int64 now_ticks = (now - _epoch_time).ticks(); + + std::list live_streams; + std::list closed_streams; + int live_count = 0; + { + ScopedLocker _(_stream_map_lock); + for (StreamMap::iterator it = _stream_map.begin(); it != _stream_map.end(); ) + { + const RpcClientStreamPtr& stream = it->second; + + if (_keep_alive_ticks != -1 + && now_ticks - stream->last_rw_ticks() >= _keep_alive_ticks) + { + stream->close("keep alive timeout"); + } + + if (stream->is_closed()) + { + closed_streams.push_back(stream); + _stream_map.erase(it++); + } + else + { + stream->reset_ticks(now_ticks); + live_streams.push_back(stream); + ++live_count; + ++it; + } + } + } + _live_stream_count = live_count; + + // flow control + if (_slice_quota_in != -1) + { + // reset quota pool + _flow_controller->reset_read_quota(_slice_quota_in); + + // collect streams need to trigger + std::vector trigger_list; + for (std::list::iterator it = live_streams.begin(); + it != live_streams.end(); ++it) + { + int token = (*it)->read_quota_token(); + if (token <= 0) + { + // only need trigger streams whose token <= 0 + trigger_list.push_back(FlowControlItem(token, (*it).get())); + } + } + + // sort by token: token closer to zero, earlier to trigger + std::sort(trigger_list.begin(), trigger_list.end()); + + // trigger in order + for (std::vector::iterator t_it = trigger_list.begin(); + t_it != trigger_list.end(); ++t_it) + { + t_it->stream->trigger_receive(); + } + } + if (_slice_quota_out != -1) + { + // reset quota pool + _flow_controller->reset_write_quota(_slice_quota_out); + + // collect streams need to trigger + std::vector trigger_list; + for (std::list::iterator it = live_streams.begin(); + it != live_streams.end(); ++it) + { + int token = (*it)->write_quota_token(); + if (token <= 0) + { + // only need trigger streams whose token <= 0 + trigger_list.push_back(FlowControlItem(token, (*it).get())); + } + } + + // sort by token: token closer to zero, earlier to trigger + std::sort(trigger_list.begin(), trigger_list.end()); + + // trigger in order + for (std::vector::iterator t_it = trigger_list.begin(); + t_it != trigger_list.end(); ++t_it) + { + t_it->stream->trigger_send(); + } + } + + if (now_ticks - _last_print_connection_ticks >= _print_connection_interval_ticks) + { + _last_print_connection_ticks = now_ticks; +#if defined( LOG ) + LOG(INFO) << "TimerMaintain(): countof(RpcListener)=" + << SOFA_PBRPC_GET_RESOURCE_COUNTER(RpcListener) + << ", countof(RpcByteStream)=" << SOFA_PBRPC_GET_RESOURCE_COUNTER(RpcByteStream) + << ", live_stream_count=" << _live_stream_count; +#else + SLOG(INFO, "TimerMaintain(): countof(RpcListener)=%d" + ", countof(RpcByteStream)=%d, live_stream_count=%d", + SOFA_PBRPC_GET_RESOURCE_COUNTER(RpcListener), + SOFA_PBRPC_GET_RESOURCE_COUNTER(RpcByteStream), + _live_stream_count); +#endif + } + + _last_maintain_ticks = now_ticks; +} + +uint64 RpcClientImpl::GenerateSequenceId() +{ + return static_cast(++_next_request_id); +} + +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_client_impl.h b/src/sofa/pbrpc/rpc_client_impl.h new file mode 100644 index 0000000..9a196e2 --- /dev/null +++ b/src/sofa/pbrpc/rpc_client_impl.h @@ -0,0 +1,131 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_RPC_CLIENT_IMPL_H_ +#define _SOFA_PBRPC_RPC_CLIENT_IMPL_H_ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace sofa { +namespace pbrpc { + +class RpcClientImpl: public sofa::pbrpc::enable_shared_from_this +{ +public: + static const int MAINTAIN_INTERVAL_IN_MS = 100; + +public: + explicit RpcClientImpl(const RpcClientOptions& options); + + virtual ~RpcClientImpl(); + + void Start(); + + void Stop(); + + RpcClientOptions GetOptions(); + + void ResetOptions(const RpcClientOptions& options); + + int ConnectionCount(); + + // Rpc call method to remote endpoint. + // + // The call can be done in following cases: + // * send failed + // * timeouted + // * response received + void CallMethod(const google::protobuf::Message* request, + google::protobuf::Message* response, + const RpcControllerImplPtr& cntl); + + const ThreadGroupImplPtr& GetCallbackThreadGroup() const; + + bool ResolveAddress(const std::string& address, + RpcEndpoint* endpoint); + +private: + // Get stream for "remote_endpoint". Return null ptr if failed. + RpcClientStreamPtr FindOrCreateStream(const RpcEndpoint& remote_endpoint); + + void StopStreams(); + + void ClearStreams(); + + void DoneCallback(google::protobuf::Message* response, + const RpcControllerImplPtr& cntl); + + bool ShouldStreamRemoved(const RpcClientStreamPtr& stream); + + void TimerMaintain(const PTime& now); + + uint64 GenerateSequenceId(); + +private: + struct FlowControlItem + { + int token; // always <= 0 + RpcClientStream* stream; + + FlowControlItem(int t, RpcClientStream* s) : token(t), stream(s) {} + // comparator: nearer to zero, higher priority + bool operator< (const FlowControlItem& o) const + { + return token > o.token; + } + }; + +private: + RpcClientOptions _options; + volatile bool _is_running; + MutexLock _start_stop_lock; + + AtomicCounter64 _next_request_id; + + PTime _epoch_time; + int64 _ticks_per_second; + int64 _last_maintain_ticks; + int64 _last_print_connection_ticks; + + int64 _slice_count; + int64 _slice_quota_in; + int64 _slice_quota_out; + int64 _max_pending_buffer_size; + int64 _keep_alive_ticks; + int64 _print_connection_interval_ticks; + + FlowControllerPtr _flow_controller; + + ThreadGroupImplPtr _maintain_thread_group; + ThreadGroupImplPtr _callback_thread_group; + ThreadGroupImplPtr _work_thread_group; + + TimerWorkerPtr _timer_worker; + RpcTimeoutManagerPtr _timeout_manager; + + typedef std::map StreamMap; + StreamMap _stream_map; + FastLock _stream_map_lock; + volatile int _live_stream_count; + + SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(RpcClientImpl); +}; // class RpcClientImpl + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_RPC_CLIENT_IMPL_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_client_stream.h b/src/sofa/pbrpc/rpc_client_stream.h new file mode 100644 index 0000000..8d1eab0 --- /dev/null +++ b/src/sofa/pbrpc/rpc_client_stream.h @@ -0,0 +1,255 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_RPC_CLIENT_STREAM_H_ +#define _SOFA_PBRPC_RPC_CLIENT_STREAM_H_ + +#include +#include +#include +#include + +namespace sofa { +namespace pbrpc { + +class RpcClientStream : public RpcMessageStream +{ +public: + RpcClientStream(IOService& io_service, const RpcEndpoint& endpoint) + : RpcMessageStream(ROLE_TYPE_CLIENT, io_service, endpoint) + {} + + virtual ~RpcClientStream() + { + SOFA_PBRPC_FUNCTION_TRACE; + close("stream destructed"); + for (ControllerMap::iterator it = _controller_map.begin(); + it != _controller_map.end(); ++it) + { + it->second->Done(RPC_ERROR_CONNECTION_CLOSED, _error_message); + } + } + + void call_method(const RpcControllerImplPtr& cntl) + { + SOFA_PBRPC_FUNCTION_TRACE; + + if (is_closed()) + { +#if defined( LOG ) + LOG(ERROR) << "call_method(): " << RpcEndpointToString(_remote_endpoint) + << ": stream already closed: " << _error_message; +#else + SLOG(ERROR, "call_method(): %s: stream already closed: %s", + RpcEndpointToString(_remote_endpoint).c_str(), _error_message); +#endif + cntl->Done(RPC_ERROR_CONNECTION_CLOSED, _error_message); + return; + } + + // add to map + uint64 sequence_id = cntl->SequenceId(); + { + ScopedLocker _(_controller_map_lock); + _controller_map[sequence_id] = cntl; + } + + /// !!!Attention: the call may be already done at this point. + async_send_message(cntl->RequestBuffer(), cntl); + } + +private: + virtual void on_closed() + { + SOFA_PBRPC_FUNCTION_TRACE; + + ControllerMap tmp_map; + { + ScopedLocker _(_controller_map_lock); + tmp_map.swap(_controller_map); + } + + for (ControllerMap::iterator it = tmp_map.begin(); + it != tmp_map.end(); ++it) + { + it->second->Done(RPC_ERROR_CONNECTION_CLOSED, _error_message); + } + } + + virtual bool on_sending( + const ReadBufferPtr& /* request_message */, + const RpcControllerImplPtr& cntl) + { + SOFA_PBRPC_FUNCTION_TRACE; + + // if already done (may be done by timeout manager), + // should cancel sending. + return !cntl->IsDone() && !cntl->IsStartCancel(); + } + + virtual void on_sent( + const ReadBufferPtr& request_message, + const RpcControllerImplPtr& cntl) + { + SOFA_PBRPC_FUNCTION_TRACE; + + // the request has been sent. + cntl->NotifyRequestSent(_local_endpoint, request_message->TotalCount()); + } + + virtual void on_send_failed( + RpcErrorCode error_code, + const ReadBufferPtr& /* request_message */, + const RpcControllerImplPtr& cntl) + { + SOFA_PBRPC_FUNCTION_TRACE; + + // TODO more efficient sync map + // remove the call handle from map + uint64 sequence_id = cntl->SequenceId(); + { + ScopedLocker _(_controller_map_lock); + _controller_map.erase(sequence_id); + } + + cntl->Done(error_code, _error_message); + } + + virtual void on_received( + const ReadBufferPtr& message, + int meta_size, + int64 data_size) + { + SOFA_PBRPC_FUNCTION_TRACE; + + RpcMeta meta; + if (!meta.ParseFromBoundedZeroCopyStream(message.get(), meta_size)) + { +#if defined( LOG ) + LOG(ERROR) << "on_received(): " << RpcEndpointToString(_remote_endpoint) + << ": parse rpc meta failed, ignore"; +#else + SLOG(ERROR, "on_received(): %s: parse rpc meta failed, ignore", + RpcEndpointToString(_remote_endpoint).c_str()); +#endif + return; + } + + if (meta.type() != RpcMeta::RESPONSE) + { + // TODO handle un-expected message type + // + // just ignore it +#if defined( LOG ) + LOG(ERROR) << "on_received(): " << RpcEndpointToString(_remote_endpoint) + << " {" << meta.sequence_id() << "}" + << ": un-expected message type " << meta.type() << ", ignore"; +#else + SLOG(ERROR, "on_received(): %s {%lu}: un-expected message type %d, ignore", + RpcEndpointToString(_remote_endpoint).c_str(), + meta.sequence_id(), meta.type()); +#endif + return; + } + + // find corresponding call handle and erase from map + // TODO more efficient sync map + RpcControllerImplPtr cntl; + { + ScopedLocker _(_controller_map_lock); + ControllerMap::iterator it = _controller_map.find(meta.sequence_id()); + if (it != _controller_map.end()) + { + cntl = it->second; + _controller_map.erase(it); + } + } + + if (!cntl) + { + // TODO handle un-expected sequence id + // + // just ignore it +#if defined( LOG ) + LOG(ERROR) << "on_received(): " << RpcEndpointToString(_remote_endpoint) + << " {" << meta.sequence_id() << "}" + << ": sequence id not found, ignore"; +#else + SLOG(ERROR, "on_received(): %s {%lu}: sequence id not found, ignore", + RpcEndpointToString(_remote_endpoint).c_str(), meta.sequence_id()); +#endif + return; + } + + if (!meta.has_failed()) + { +#if defined( LOG ) + LOG(ERROR) << "on_received(): " << RpcEndpointToString(_remote_endpoint) + << " {" << meta.sequence_id() << "}" + << ": bad rpc meta: \"failed\" field not set"; +#else + SLOG(ERROR, "on_received(): %s {%lu}: bad rpc meta: \"failed\" field not set", + RpcEndpointToString(_remote_endpoint).c_str(), meta.sequence_id()); +#endif + cntl->Done(RPC_ERROR_PARSE_RESPONSE_MESSAGE, "rpc meta: \"failed\" field not set"); + } + else if (meta.failed()) + { + if (!meta.has_error_code()) + { +#if defined( LOG ) + LOG(ERROR) << "on_received(): " << RpcEndpointToString(_remote_endpoint) + << " {" << meta.sequence_id() << "}" + << ": bad rpc meta: \"error_code\" field not set"; +#else + SLOG(ERROR, "on_received(): %s {%lu}: bad rpc meta: \"error_code\" field not set", + RpcEndpointToString(_remote_endpoint).c_str(), meta.sequence_id()); +#endif + cntl->Done(RPC_ERROR_PARSE_RESPONSE_MESSAGE, "rpc meta: \"error_code\" field not set"); + } + else if (!meta.has_reason()) + { +#if defined( LOG ) + LOG(ERROR) << "on_received(): " << RpcEndpointToString(_remote_endpoint) + << " {" << meta.sequence_id() << "}" + << ": bad rpc meta: \"reason\" field not set"; +#else + SLOG(ERROR, "on_received(): %s {%lu}: bad rpc meta: \"reason\" field not set", + RpcEndpointToString(_remote_endpoint).c_str(), meta.sequence_id()); +#endif + cntl->Done(RPC_ERROR_PARSE_RESPONSE_MESSAGE, "rpc meta: \"reason\" field not set"); + } + else + { + cntl->Done(meta.error_code(), meta.reason()); + } + } + else // !meta.failed() + { + SCHECK_EQ(data_size, message->TotalCount() - message->ByteCount()); + cntl->SetResponseBuffer(message); + cntl->SetResponseCompressType(meta.has_compress_type() ? + meta.compress_type() : CompressTypeNone); + cntl->Done(RPC_SUCCESS, "succeed"); + } + } + +private: + // sequence_id ==> RpcControllerImplPtr + // TODO more efficient sync map + typedef std::map ControllerMap; + ControllerMap _controller_map; + FastLock _controller_map_lock; + + SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(RpcClientStream); +}; // class RpcClientStream + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_RPC_CLIENT_STREAM_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_controller.cc b/src/sofa/pbrpc/rpc_controller.cc new file mode 100644 index 0000000..6b15d11 --- /dev/null +++ b/src/sofa/pbrpc/rpc_controller.cc @@ -0,0 +1,105 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include +#include + +namespace sofa { +namespace pbrpc { + +RpcController::RpcController() + : _impl(new RpcControllerImpl()) +{ +} + +RpcController::~RpcController() +{ +} + +std::string RpcController::LocalAddress() const +{ + return RpcEndpointToString(_impl->LocalEndpoint()); +} + +std::string RpcController::RemoteAddress() const +{ + return RpcEndpointToString(_impl->RemoteEndpoint()); +} + +void RpcController::Reset() +{ + _impl.reset(new RpcControllerImpl()); +} + +void RpcController::SetTimeout(int64 timeout_in_ms) +{ + _impl->SetTimeout(timeout_in_ms); +} + +int64 RpcController::Timeout() const +{ + return _impl->Timeout(); +} + +void RpcController::SetRequestCompressType(CompressType compress_type) +{ + _impl->SetRequestCompressType(compress_type); +} + +void RpcController::SetResponseCompressType(CompressType compress_type) +{ + _impl->SetResponseCompressType(compress_type); +} + +bool RpcController::Failed() const +{ + return _impl->Failed(); +} + +int RpcController::ErrorCode() const +{ + return _impl->ErrorCode(); +} + +std::string RpcController::ErrorText() const +{ + return _impl->ErrorText(); +} + +bool RpcController::IsRequestSent() const +{ + return _impl->IsRequestSent(); +} + +int64 RpcController::SentBytes() const +{ + return _impl->SentBytes(); +} + +void RpcController::StartCancel() +{ + _impl->StartCancel(); +} + +void RpcController::SetFailed(const std::string& reason) +{ + _impl->SetFailed(reason); +} + +bool RpcController::IsCanceled() const +{ + return _impl->IsCanceled(); +} + +void RpcController::NotifyOnCancel(google::protobuf::Closure* callback) +{ + _impl->NotifyOnCancel(callback); +} + +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_controller.h b/src/sofa/pbrpc/rpc_controller.h new file mode 100644 index 0000000..c267208 --- /dev/null +++ b/src/sofa/pbrpc/rpc_controller.h @@ -0,0 +1,169 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_RPC_CONTROLLER_H_ +#define _SOFA_PBRPC_RPC_CONTROLLER_H_ + +#include + +#include +#include + +namespace sofa { +namespace pbrpc { + +class RpcControllerImpl; + +class RpcController : public google::protobuf::RpcController +{ +public: + RpcController(); + virtual ~RpcController(); + + // -------- used by both client and server side --------- + // These calls can be made from both client side and server side. + + // Get the local address in format of "ip:port". + // + // For client: + // This method can only be called after the call has finished. If + // IsRequestSent() is true, returns the local address used for sending + // the message; else, the return value is undefined. + // + // For server: + // This method returns the local address where the message received from. + std::string LocalAddress() const; + + // Get the remote address in format of "ip:port". + // + // For client: + // This method returns the remote address where the messsage sent to. + // + // For server: + // This method returns the remote address where the message received from. + std::string RemoteAddress() const; + + // -------- used only by client side --------- + // These calls should be made from the client side only. Their results are + // undefined on the server side (may crash). + + // Resets the RpcController to its initial state so that it may be reused + // in a new call. Must not be called while it is in use. + virtual void Reset(); + + // Set expect timeout in milli-seconds of the call. If timeout is not set + // or set no more than 0, actual timeout will be taken from proto options. + void SetTimeout(int64 timeout_in_ms); + + // Get the actual timeout in milli-seconds. + // + // The actual timeout takes effect in the following order: + // * set in RpcController (take effective only when timeout > 0) + // * set in the method proto options (default not set) + // * set in the service proto options (default value is 10 seconds) + int64 Timeout() const; + + // Set compress type of the request message. + // Supported types: + // CompressTypeNone + // CompressTypeGzip + // CompressTypeZlib + // CompressTypeSnappy + // CompressTypeLZ4 + void SetRequestCompressType(CompressType compress_type); + + // Set expected compress type of the response message. + // Supported types: + // CompressTypeNone + // CompressTypeGzip + // CompressTypeZlib + // CompressTypeSnappy + // CompressTypeLZ4 + void SetResponseCompressType(CompressType compress_type); + + // After a call has finished, returns true if the call failed. The possible + // reasons for failure depend on the RPC implementation. Failed() must not + // be called before a call has finished. If Failed() returns true, the + // contents of the response message are undefined. + // + // This method can only be called after the call has finished. + virtual bool Failed() const; + + // If Failed() is true, returns error code which identities the reason. + // The error code is of type RpcErrorCode. + // + // This method can only be called after the call has finished. + virtual int ErrorCode() const; + + // If Failed() is true, returns a human-readable description of the error. + // This can only be called after the call has finished. + // + // This method can only be called after the call has finished. + virtual std::string ErrorText() const; + + // If the request has already been set to the remote server, returns true; + // otherwise returns false. + // + // This method can only be called after the call has finished. + bool IsRequestSent() const; + + // If IsRequestSent() is true, returns sent bytes, including the rpc header. + // + // This method can only be called after the call has finished. + int64 SentBytes() const; + + // Advises the RPC system that the caller desires that the RPC call be + // canceled. The RPC system may cancel it immediately, may wait awhile and + // then cancel it, or may not even cancel the call at all. If the call is + // canceled, the "done" callback will still be called and the RpcController + // will indicate that the call failed at that time. + // + // Not supported now. + virtual void StartCancel(); + + // -------- used only by server side --------- + // These calls should be made from the server side only. Their results + // are undefined on the client side (may crash). + + // Causes Failed() to return true on the client side. "reason" will be + // incorporated into the message returned by ErrorText(). If you find + // you need to return machine-readable information about failures, you + // should incorporate it into your response protocol buffer and should + // NOT call SetFailed(). + virtual void SetFailed(const std::string& reason); + + // If true, indicates that the client canceled the RPC, so the server may + // as well give up on replying to it. The server should still call the + // final "done" callback. + virtual bool IsCanceled() const; + + // Asks that the given callback be called when the RPC is canceled. The + // callback will always be called exactly once. If the RPC completes without + // being canceled, the callback will be called after completion. If the RPC + // has already been canceled when NotifyOnCancel() is called, the callback + // will be called immediately. + // + // NotifyOnCancel() must be called no more than once per request. + virtual void NotifyOnCancel(google::protobuf::Closure* callback); + +public: + const sofa::pbrpc::shared_ptr& impl() const + { + return _impl; + } + +private: + sofa::pbrpc::shared_ptr _impl; + + SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(RpcController); +}; // class RpcController + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_RPC_CONTROLLER_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_controller_impl.h b/src/sofa/pbrpc/rpc_controller_impl.h new file mode 100644 index 0000000..2cb99b8 --- /dev/null +++ b/src/sofa/pbrpc/rpc_controller_impl.h @@ -0,0 +1,408 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_RPC_CONTROLLER_IMPL_H_ +#define _SOFA_PBRPC_RPC_CONTROLLER_IMPL_H_ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace sofa { +namespace pbrpc { + +#define CompressTypeAuto ((CompressType)-1) + +class RpcControllerImpl : public sofa::pbrpc::enable_shared_from_this +{ +public: + typedef boost::function InternalDoneCallback; + +public: + RpcControllerImpl() + : _sequence_id(0) + , _error_code(RPC_SUCCESS) + , _is_done(NOT_DONE) + , _is_request_sent(false) + , _sent_bytes(0) + , _is_start_cancel(false) + , _is_sync(false) + , _timeout_id(0) + {} + + virtual ~RpcControllerImpl() {} + + void SetRequestCompressType(CompressType compress_type) + { + _user_options.request_compress_type = compress_type; + } + + CompressType RequestCompressType() + { + return _user_options.request_compress_type != CompressTypeAuto ? + _user_options.request_compress_type : _auto_options.request_compress_type; + } + + void SetResponseCompressType(CompressType compress_type) + { + _user_options.response_compress_type = compress_type; + } + + CompressType ResponseCompressType() + { + return _user_options.response_compress_type != CompressTypeAuto ? + _user_options.response_compress_type : _auto_options.response_compress_type; + } + + void SetTimeout(int64 timeout) + { + _user_options.timeout = timeout; + } + + int64 Timeout() const + { + return _user_options.timeout > 0 ? + _user_options.timeout : _auto_options.timeout; + } + + bool Failed() const + { + return _error_code != RPC_SUCCESS; + } + + int ErrorCode() const + { + return _error_code; + } + + const std::string& Reason() const + { + return _reason; + } + + std::string ErrorText() const + { + if (_reason.empty()) { + return RpcErrorCodeToString(_error_code); + } else { + return RpcErrorCodeToString(_error_code) + + std::string(": ") + _reason; + } + } + + void StartCancel() + { + // TODO to support + } + + void SetFailed(const std::string& reason) + { + SetFailed(RPC_ERROR_FROM_USER, reason); + } + + bool IsCanceled() const + { + // TODO to support + return false; + } + + void NotifyOnCancel(google::protobuf::Closure* /* callback */) + { + // TODO to support + } + + + // ----------------------------------------------------------------- + // Used both in client and server. + // ----------------------------------------------------------------- + void SetSequenceId(uint64 sequence_id) + { + _sequence_id = sequence_id; + } + + uint64 SequenceId() const + { + return _sequence_id; + } + + void SetMethodId(const std::string& method_id) + { + _method_id = method_id; + } + + const std::string& MethodId() const + { + return _method_id; + } + + void SetLocalEndpoint(const RpcEndpoint& local_endpoint) + { + _local_endpoint = local_endpoint; + } + + const RpcEndpoint& LocalEndpoint() const + { + return _local_endpoint; + } + + void SetRemoteEndpoint(const RpcEndpoint& remote_endpoint) + { + _remote_endpoint = remote_endpoint; + } + + const RpcEndpoint& RemoteEndpoint() const + { + return _remote_endpoint; + } + + void SetFailed(int error_code, const std::string& reason) + { + _error_code = error_code; + _reason = reason; + if (_error_code == RPC_ERROR_REQUEST_TIMEOUT) + { + _reason += _is_request_sent ? + ": request already sent to remote" : + ": request not sent to remote"; + } + } + + + // ----------------------------------------------------------------- + // Used only in client. + // ----------------------------------------------------------------- + bool IsDone() const + { + return _is_done == DONE; + } + + bool IsRequestSent() const + { + return _is_request_sent; + } + + int64 SentBytes() const + { + return _sent_bytes; + } + + bool IsStartCancel() const + { + return _is_start_cancel; + } + + void PushDoneCallback(const InternalDoneCallback& callback) + { + SCHECK(callback); + _done_callbacks.push_back(callback); + } + + void Done(int error_code, const std::string& reason) + { + // make sure that the callback is only called once. + if (atomic_comp_swap(&_is_done, DONE, NOT_DONE) == NOT_DONE) + { + SetFailed(error_code, reason); + + while (!_done_callbacks.empty()) + { + const InternalDoneCallback& callback = _done_callbacks.back(); + callback(shared_from_this()); + _done_callbacks.pop_back(); + } + } + } + + void FillFromMethodDescriptor(const google::protobuf::MethodDescriptor* method) + { + _method_id = method->full_name(); + if (_user_options.timeout <= 0) + { + int64 timeout_in_ms = method->options().HasExtension(method_timeout) ? + method->options().GetExtension(method_timeout) : + method->service()->options().GetExtension(service_timeout); + if (timeout_in_ms <= 0) { + // Just a protection, it shouldn't happen. + timeout_in_ms = 1; + } + _auto_options.timeout = timeout_in_ms; + } + if (_user_options.request_compress_type == CompressTypeAuto) { + _auto_options.request_compress_type = + method->options().HasExtension(request_compress_type) ? + method->options().GetExtension(request_compress_type) : + CompressTypeNone; + } + if (_user_options.response_compress_type == CompressTypeAuto) { + _auto_options.response_compress_type = + method->options().HasExtension(response_compress_type) ? + method->options().GetExtension(response_compress_type) : + CompressTypeNone; + } + } + + void SetSync() + { + _is_sync = true; + } + + bool IsSync() const + { + return _is_sync; + } + + void SetWaitEvent(const WaitEventPtr& wait_event) + { + _wait_event = wait_event; + } + + const WaitEventPtr& WaitEvent() const + { + return _wait_event; + } + + void SetRpcClientStream(const RpcClientStreamWPtr& stream) + { + _client_stream = stream; + } + + const RpcClientStreamWPtr& RpcClientStream() const + { + return _client_stream; + } + + void StartTimer() + { + int64 timeout = Timeout(); + _expiration = timeout <= 0 ? ptime_infin() + : ptime_now() + time_duration_milliseconds(timeout); + } + + const PTime& Expiration() const + { + return _expiration; + } + + void SetTimeoutId(uint64 timeout_id) + { + _timeout_id = timeout_id; + } + + uint64 TimeoutId() const + { + return _timeout_id; + } + + void SetRequestBuffer(const ReadBufferPtr& request_buffer) + { + _request_buffer = request_buffer; + } + + const ReadBufferPtr& RequestBuffer() const + { + return _request_buffer; + } + + void SetResponseBuffer(const ReadBufferPtr& response_buffer) + { + _response_buffer = response_buffer; + } + + const ReadBufferPtr& ResponseBuffer() const + { + return _response_buffer; + } + + void NotifyRequestSent(const RpcEndpoint& local_endpoint, int64 sent_bytes) + { + _is_request_sent = true; + _local_endpoint = local_endpoint; + _sent_bytes = sent_bytes; + _request_sent_time = ptime_now(); + } + + + // ----------------------------------------------------------------- + // Used only in server. + // ----------------------------------------------------------------- + void SetRpcServerStream(const RpcServerStreamWPtr& stream) + { + _server_stream = stream; + } + + const RpcServerStreamWPtr& RpcServerStream() const + { + return _server_stream; + } + + void SetRequestReceivedTime(const PTime& time) + { + _request_received_time = time; + } + + const PTime& RequestReceivedTime() + { + return _request_received_time; + } + +private: + uint64 _sequence_id; + std::string _method_id; + RpcEndpoint _local_endpoint; + RpcEndpoint _remote_endpoint; + int _error_code; + std::string _reason; + + // used only in client side + static const int NOT_DONE = 0; + static const int DONE = 1; + volatile int _is_done; // 0 means not done, 1 means aleady done + bool _is_request_sent; // if the request has been sent + int64 _sent_bytes; // sent bytes including the header + bool _is_start_cancel; // if has started canceling the call + std::deque _done_callbacks; // internal done callbacks + bool _is_sync; + WaitEventPtr _wait_event; // used only for sync call + RpcClientStreamWPtr _client_stream; + PTime _expiration; + uint64 _timeout_id; + ReadBufferPtr _request_buffer; + ReadBufferPtr _response_buffer; + PTime _request_sent_time; + + struct RequestOptions { + int64 timeout; + CompressType request_compress_type; + CompressType response_compress_type; + RequestOptions() : + timeout(0), + request_compress_type(CompressTypeAuto), + response_compress_type(CompressTypeAuto) {} + }; + RequestOptions _user_options; // options set by user + RequestOptions _auto_options; // options from proto + + // used only in server side + RpcServerStreamWPtr _server_stream; + PTime _request_received_time; + + SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(RpcControllerImpl); +}; // class RpcControllerImpl + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_RPC_CONTROLLER_IMPL_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_endpoint.cc b/src/sofa/pbrpc/rpc_endpoint.cc new file mode 100644 index 0000000..ef85535 --- /dev/null +++ b/src/sofa/pbrpc/rpc_endpoint.cc @@ -0,0 +1,70 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include + +#include + +namespace sofa { +namespace pbrpc { + +using boost::asio::ip::tcp; + +std::string RpcEndpointToString(const RpcEndpoint& endpoint) +{ + std::stringstream ss; + ss << endpoint; + return ss.str(); +} + +bool ResolveAddress(IOService& io_service, + const std::string& host, const std::string& svc, + RpcEndpoint* endpoint) +{ + tcp::resolver resolver(io_service); + boost::system::error_code ec; + tcp::resolver::iterator it = resolver.resolve(tcp::resolver::query(host, svc), ec), end; + if (it != end) + { + *endpoint = it->endpoint(); + return true; + } + else + { +#if defined( LOG ) + LOG(ERROR) << "ResolveAddress(): resolve address [" + << host << ":" << svc << "] failed: " << ec.message(); +#else + SLOG(ERROR, "ResolveAddress(): resolve address [%s:%s] failed: %s", + host.c_str(), svc.c_str(), ec.message().c_str()); +#endif + return false; + } +} + +bool ResolveAddress(IOService& io_service, + const std::string& address, + RpcEndpoint* endpoint) +{ + std::string::size_type pos = address.find(':'); + if (pos == std::string::npos) + { +#if defined( LOG ) + LOG(ERROR) << "ResolveAddress(): invalid address: " << address; +#else + SLOG(ERROR, "ResolveAddress(): invalid address: %s", address.c_str()); +#endif + return false; + } + std::string host = address.substr(0, pos); + std::string svc = address.substr(pos + 1); + return ResolveAddress(io_service, host, svc, endpoint); +} + +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_endpoint.h b/src/sofa/pbrpc/rpc_endpoint.h new file mode 100644 index 0000000..a2f05a4 --- /dev/null +++ b/src/sofa/pbrpc/rpc_endpoint.h @@ -0,0 +1,32 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_RPC_ENDPOINT_H_ +#define _SOFA_PBRPC_RPC_ENDPOINT_H_ + +#include + +namespace sofa { +namespace pbrpc { + +typedef boost::asio::ip::tcp::endpoint RpcEndpoint; + +std::string RpcEndpointToString(const RpcEndpoint& endpoint); + +bool ResolveAddress(IOService& io_service, + const std::string& host, const std::string& svc, + RpcEndpoint* endpoint); + +bool ResolveAddress(IOService& io_service, + const std::string& address, + RpcEndpoint* endpoint); + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_RPC_ENDPOINT_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_error_code.cc b/src/sofa/pbrpc/rpc_error_code.cc new file mode 100644 index 0000000..92b0538 --- /dev/null +++ b/src/sofa/pbrpc/rpc_error_code.cc @@ -0,0 +1,48 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include + +namespace sofa { +namespace pbrpc { + +#define MAKE_CASE(name) case name: return (#name) + +const char* RpcErrorCodeToString(int error_code) +{ + switch(error_code) + { + MAKE_CASE(RPC_SUCCESS); + MAKE_CASE(RPC_ERROR_PARSE_REQUEST_MESSAGE); + MAKE_CASE(RPC_ERROR_PARSE_RESPONSE_MESSAGE); + MAKE_CASE(RPC_ERROR_UNCOMPRESS_MESSAGE); + MAKE_CASE(RPC_ERROR_COMPRESS_TYPE); + MAKE_CASE(RPC_ERROR_NOT_SPECIFY_METHOD_NAME); + MAKE_CASE(RPC_ERROR_PARSE_METHOD_NAME); + MAKE_CASE(RPC_ERROR_FOUND_SERVICE); + MAKE_CASE(RPC_ERROR_FOUND_METHOD); + MAKE_CASE(RPC_ERROR_CHANNEL_BROKEN); + MAKE_CASE(RPC_ERROR_CONNECTION_CLOSED); + MAKE_CASE(RPC_ERROR_REQUEST_TIMEOUT); + MAKE_CASE(RPC_ERROR_REQUEST_CANCELED); + MAKE_CASE(RPC_ERROR_SERVER_UNAVAILABLE); + MAKE_CASE(RPC_ERROR_SERVER_UNREACHABLE); + MAKE_CASE(RPC_ERROR_SERVER_SHUTDOWN); + MAKE_CASE(RPC_ERROR_SEND_BUFFER_FULL); + MAKE_CASE(RPC_ERROR_SERIALIZE_REQUEST); + MAKE_CASE(RPC_ERROR_RESOLVE_ADDRESS); + MAKE_CASE(RPC_ERROR_CREATE_STREAM); + MAKE_CASE(RPC_ERROR_NOT_IN_RUNNING); + MAKE_CASE(RPC_ERROR_UNKNOWN); + MAKE_CASE(RPC_ERROR_FROM_USER); + } + return "RPC_ERROR_UNDEFINED"; +} + +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_error_code.h b/src/sofa/pbrpc/rpc_error_code.h new file mode 100644 index 0000000..a50646a --- /dev/null +++ b/src/sofa/pbrpc/rpc_error_code.h @@ -0,0 +1,52 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_RPC_ERROR_CODE_H_ +#define _SOFA_PBRPC_RPC_ERROR_CODE_H_ + +namespace sofa { +namespace pbrpc { + +enum RpcErrorCode { + RPC_SUCCESS = 0, + RPC_ERROR_PARSE_REQUEST_MESSAGE = 1, + RPC_ERROR_PARSE_RESPONSE_MESSAGE = 2, + RPC_ERROR_UNCOMPRESS_MESSAGE = 3, + RPC_ERROR_COMPRESS_TYPE = 4, + RPC_ERROR_NOT_SPECIFY_METHOD_NAME = 5, + RPC_ERROR_PARSE_METHOD_NAME = 6, + RPC_ERROR_FOUND_SERVICE = 7, + RPC_ERROR_FOUND_METHOD = 8, + RPC_ERROR_CHANNEL_BROKEN = 9, + RPC_ERROR_CONNECTION_CLOSED = 10, + RPC_ERROR_REQUEST_TIMEOUT = 11, // request timeout + RPC_ERROR_REQUEST_CANCELED = 12, // request canceled + RPC_ERROR_SERVER_UNAVAILABLE = 13, // server un-healthy + RPC_ERROR_SERVER_UNREACHABLE = 14, // server un-reachable + RPC_ERROR_SERVER_SHUTDOWN = 15, + RPC_ERROR_SEND_BUFFER_FULL = 16, + RPC_ERROR_SERIALIZE_REQUEST = 17, + RPC_ERROR_SERIALIZE_RESPONSE = 18, + RPC_ERROR_RESOLVE_ADDRESS = 19, + RPC_ERROR_CREATE_STREAM = 20, + RPC_ERROR_NOT_IN_RUNNING = 21, + + // error code for listener + RPC_ERROR_TOO_MANY_OPEN_FILES = 101, + + RPC_ERROR_UNKNOWN = 999, + RPC_ERROR_FROM_USER = 1000, +}; // enum RpcErrorCode + +// Convert rpc error code to human readable string. +const char* RpcErrorCodeToString(int error_code); + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_RPC_ERROR_CODE_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_listener.h b/src/sofa/pbrpc/rpc_listener.h new file mode 100644 index 0000000..ac0f0e8 --- /dev/null +++ b/src/sofa/pbrpc/rpc_listener.h @@ -0,0 +1,236 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_RPC_LISTENER_H_ +#define _SOFA_PBRPC_RPC_LISTENER_H_ + +#include +#include +#include +#include + +namespace sofa { +namespace pbrpc { + +using boost::asio::ip::tcp; + +class RpcListener : public sofa::pbrpc::enable_shared_from_this +{ + // Callback function when created or accepted a new connection. + typedef boost::function Callback; + typedef boost::function FailCallback; + +public: + static const int LISTEN_MAX_CONNECTIONS = 4096; + +public: + RpcListener(IOService& io_service, const RpcEndpoint& endpoint) + : _io_service(io_service) + , _endpoint(endpoint) + , _endpoint_str(RpcEndpointToString(endpoint)) + , _acceptor(io_service) + , _is_closed(false) + { + SOFA_PBRPC_INC_RESOURCE_COUNTER(RpcListener); + } + + virtual ~RpcListener() + { + SOFA_PBRPC_FUNCTION_TRACE; + close(); + SOFA_PBRPC_DEC_RESOURCE_COUNTER(RpcListener); + } + + void close() + { + ScopedLocker _(_close_lock); + if (_is_closed) return; + _is_closed = true; + + boost::system::error_code ec; + _acceptor.cancel(ec); + _acceptor.close(ec); + +#if defined( LOG ) + LOG(INFO) << "close(): listener closed: " << _endpoint_str; +#else + SLOG(INFO, "close(): listener closed: %s", _endpoint_str.c_str()); +#endif + } + + bool is_closed() + { + ScopedLocker _(_close_lock); + return _is_closed; + } + + // Set the callback funtion when created a new connection. + template + void set_create_callback(const T& create_callback) + { + _create_callback = create_callback; + } + + // Set the callback funtion when accepted a new connection. + template + void set_accept_callback(const T& accept_callback) + { + _accept_callback = accept_callback; + } + + // Set the callback funtion when failed to accept connection. + template + void set_accept_fail_callback(const T& accept_fail_callback) + { + _accept_fail_callback = accept_fail_callback; + } + + // Start listen. Return false if failed. + bool start_listen() + { + boost::system::error_code ec; + + _acceptor.open(_endpoint.protocol(), ec); + if (ec) + { +#if defined( LOG ) + LOG(ERROR) << "start_listen(): open acceptor failed: " + << _endpoint_str << ": " << ec.message(); +#else + SLOG(ERROR, "start_listen(): open acceptor failed: %s: %s", + _endpoint_str.c_str(), ec.message().c_str()); +#endif + return false; + } + + _acceptor.set_option(tcp::acceptor::reuse_address(true), ec); + if (ec) + { +#if defined( LOG ) + LOG(ERROR) << "start_listen(): set acceptor option failed: " + << _endpoint_str << ": " << ec.message(); +#else + SLOG(ERROR, "start_listen(): set acceptor option failed: %s: %s", + _endpoint_str.c_str(), ec.message().c_str()); +#endif + return false; + } + + _acceptor.bind(_endpoint, ec); + if (ec) + { +#if defined( LOG ) + LOG(ERROR) << "start_listen(): bind acceptor failed: " + << _endpoint_str << ": " << ec.message(); +#else + SLOG(ERROR, "start_listen(): bind acceptor failed: %s: %s", + _endpoint_str.c_str(), ec.message().c_str()); +#endif + return false; + } + + //_acceptor.listen(boost::asio::socket_base::max_connections, ec); + _acceptor.listen(LISTEN_MAX_CONNECTIONS, ec); + if (ec) + { +#if defined( LOG ) + LOG(ERROR) << "start_listen(): listen acceptor failed: " + << _endpoint_str << ": " << ec.message(); +#else + SLOG(ERROR, "start_listen(): listen acceptor failed: %s: %s", + _endpoint_str.c_str(), ec.message().c_str()); +#endif + return false; + } + +#if defined( LOG ) + LOG(INFO) << "start_listen(): listen succeed: " << _endpoint_str; +#else + SLOG(INFO, "start_listen(): listen succeed: %s", _endpoint_str.c_str()); +#endif + + async_accept(); + + return true; + } + +private: + void async_accept() + { + RpcServerStreamPtr stream(new RpcServerStream(_io_service)); + + if (_create_callback) + _create_callback(stream); + + _acceptor.async_accept(stream->socket(), boost::bind( + &RpcListener::on_accept, shared_from_this(), stream, _1)); + } + + void on_accept(const RpcServerStreamPtr& stream, + const boost::system::error_code& ec) + { + if (_is_closed) + return; + + if (ec) + { +#if defined( LOG ) + LOG(ERROR) << "on_accept(): accept error at " + << _endpoint_str << ": " << ec.message(); +#else + SLOG(ERROR, "on_accept(): accept error at %s: %s", + _endpoint_str.c_str(), ec.message().c_str()); +#endif + + close(); + + if (_accept_fail_callback) + { + RpcErrorCode error_code = ec == boost::asio::error::no_descriptors ? + RPC_ERROR_TOO_MANY_OPEN_FILES : RPC_ERROR_UNKNOWN; + _accept_fail_callback(error_code, ec.message()); + } + } + else + { + if (_accept_callback) + _accept_callback(stream); + + stream->set_socket_connected(); + +#if defined( LOG ) + LOG(INFO) << "on_accept(): accept connection at " + << _endpoint_str << ": " << RpcEndpointToString(stream->remote_endpoint()); +#else + SLOG(INFO, "on_accept(): accept connection at %s: %s", + _endpoint_str.c_str(), RpcEndpointToString(stream->remote_endpoint()).c_str()); +#endif + + async_accept(); + } + } + +private: + IOService& _io_service; + RpcEndpoint _endpoint; + std::string _endpoint_str; + Callback _create_callback; + Callback _accept_callback; + FailCallback _accept_fail_callback; + tcp::acceptor _acceptor; + volatile bool _is_closed; + MutexLock _close_lock; + + SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(RpcListener); +}; // class RpcListener + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_RPC_LISTENER_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_message_header.h b/src/sofa/pbrpc/rpc_message_header.h new file mode 100644 index 0000000..7cedcc8 --- /dev/null +++ b/src/sofa/pbrpc/rpc_message_header.h @@ -0,0 +1,43 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_RPC_MESSAGE_HEADER_H_ +#define _SOFA_PBRPC_RPC_MESSAGE_HEADER_H_ + +#include + +namespace sofa { +namespace pbrpc { + +// Magic string "SOFA" in little endian. +#define SOFA_RPC_MAGIC 1095126867u + +// total 24 bytes +struct RpcMessageHeader { + union { + char magic_str[4]; + uint32 magic_str_value; + }; // 4 bytes + int32 meta_size; // 4 bytes + int64 data_size; // 8 bytes + int64 message_size; // 8 bytes: message_size = meta_size + data_size, for check + + RpcMessageHeader() + : magic_str_value(SOFA_RPC_MAGIC) + , meta_size(0), data_size(0), message_size(0) {} + + bool CheckMagicString() const + { + return magic_str_value == SOFA_RPC_MAGIC; + } +}; + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_RPC_MESSAGE_HEADER_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_message_stream.h b/src/sofa/pbrpc/rpc_message_stream.h new file mode 100644 index 0000000..78200f2 --- /dev/null +++ b/src/sofa/pbrpc/rpc_message_stream.h @@ -0,0 +1,787 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_RPC_MESSAGE_STREAM_H_ +#define _SOFA_PBRPC_RPC_MESSAGE_STREAM_H_ + +#include + +#include +#include +#include +#include +#include +#include + +namespace sofa { +namespace pbrpc { + +// The "SendCookie" type should has default constructor, and +// should be copyable. +template +class RpcMessageStream : public RpcByteStream +{ +public: + enum RoleType { + ROLE_TYPE_SERVER = 0, + ROLE_TYPE_CLIENT = 1, + }; + +public: + RpcMessageStream(RoleType role_type, IOService& io_service, const RpcEndpoint& endpoint) + : RpcByteStream(io_service, endpoint) + , _role_type(role_type) + , _pending_message_count(0) + , _pending_data_size(0) + , _pending_buffer_size(0) + , _swapped_message_count(0) + , _swapped_data_size(0) + , _swapped_buffer_size(0) + , _max_pending_buffer_size(0) + , _read_quota_token(1) + , _write_quota_token(1) + , _total_sent_count(0) + , _total_sent_size(0) + , _total_received_count(0) + , _total_received_size(0) + , _sent_size(0) + , _sending_data(NULL) + , _sending_size(0) + , _received_message_size(0) + , _received_header_size(0) + , _receiving_header_identified(false) + , _tran_buf(NULL) + , _receiving_data(NULL) + , _receiving_size(0) + , _send_token(TOKEN_FREE) + , _receive_token(TOKEN_FREE) + {} + + virtual ~RpcMessageStream() + { + if (_tran_buf != NULL) + { + TranBufPool::free(_tran_buf); + _tran_buf = NULL; + } + } + + // Async send message to the remote endpoint. The message may be first + // put into a pending queue if the channel is busy at that time. + // + // Before starting sending data, the hook function "on_sending" will + // be called to check if the message still need to be sent. + // + // If send succeed, callback "on_sent" will be called; + // else, callback "on_send_failed" will be called. + // + // @param message the message to send, including header, meta and data. + // @param cookie a cookie affiliated to the message, which can carry some + // user's customized info. It will not be sent, but would + // be passed to the callback function. + void async_send_message( + const ReadBufferPtr& message, + const SendCookie& cookie) + { + SOFA_PBRPC_FUNCTION_TRACE; + + if (is_closed()) + { + on_send_failed(RPC_ERROR_CONNECTION_CLOSED, message, cookie); + return; + } + + put_into_pending_queue(message, cookie); + + try_start_send(); + } + + // Set the flow controller. + void set_flow_controller(const FlowControllerPtr& flow_controller) + { + _flow_controller = flow_controller; + } + + // Set the max size of pending buffer for send. + void set_max_pending_buffer_size(int64 max_pending_buffer_size) + { + _max_pending_buffer_size = max_pending_buffer_size; + } + + // Get the max size of pending buffer for send. + int64 max_pending_buffer_size() const + { + return _max_pending_buffer_size; + } + + // Get the current count of messages in the pending queue. + int pending_message_count() const + { + return _pending_message_count + _swapped_message_count; + } + + // Get the current data size of messages in the pending queue. + int64 pending_data_size() const + { + return _pending_data_size + _swapped_data_size; + } + + // Get the current buffer size occupied by the pending queue. + // This size may be larger than "pending_data_size". + int64 pending_buffer_size() const + { + return _pending_buffer_size + _swapped_buffer_size; + } + + // Trigger receiving operator. + // @return true if suceessfully triggered + virtual bool trigger_receive() + { + _read_quota_token = 1; + return try_start_receive(); + } + + // Trigger sending operator. + // @return true if suceessfully triggered + virtual bool trigger_send() + { + _write_quota_token = 1; + return try_start_send(); + } + + // Get read quota token used for sorting the trigger order. + // Always no more than 0. + int read_quota_token() const + { + return _read_quota_token; + } + + // Get write quota token used for sorting the trigger order. + // Always no more than 0. + int write_quota_token() const + { + return _write_quota_token; + } + +protected: + // Hook function on the point of starting the sending. + // + // If return true, go ahead with the sending; + // else, cancel the sending. + // + // This hook may be useful when the message stayed in a sending waiting + // queue for some time, but when dequed, it is already timeout. + virtual bool on_sending( + const ReadBufferPtr& message, + const SendCookie& cookie) = 0; + + // Callback function when send message succeed. + virtual void on_sent( + const ReadBufferPtr& message, + const SendCookie& cookie) = 0; + + // Callback function when send message failed. + virtual void on_send_failed( + RpcErrorCode error_code, + const ReadBufferPtr& message, + const SendCookie& cookie) = 0; + + // Hook function when received message. + // @param message the rough received message, including meta and data. + // @param meta_size the size of meta. + // @param data_size the size of data. + virtual void on_received( + const ReadBufferPtr& message, + int meta_size, + int64 data_size) = 0; + +private: + virtual bool on_connected() + { + SOFA_PBRPC_FUNCTION_TRACE; + + // prepare receiving + reset_receiving_env(); + if (!reset_tran_buf()) + { + close("out of memory"); + return false; + } + return true; + } + + // Callback of "async_read_some()". + virtual void on_read_some( + const boost::system::error_code& error, + std::size_t bytes_transferred) + { + SOFA_PBRPC_FUNCTION_TRACE; + + if (error) + { + if (error != boost::asio::error::eof) + { +#if defined( LOG ) + LOG(ERROR) << "on_read_some(): " << RpcEndpointToString(_remote_endpoint) + << ": read error: " << error.message(); +#else + SLOG(ERROR, "on_read_some(): %s: read error: %s", + RpcEndpointToString(_remote_endpoint).c_str(), + error.message().c_str()); +#endif + } + + close(error.message()); + return; + } + + _last_rw_ticks = _ticks; + ++_total_received_count; + _total_received_size += bytes_transferred; + + std::deque received_messages; + if (!split_and_process_message(_receiving_data, + static_cast(bytes_transferred), &received_messages)) + { + close("broken stream"); + return; + } + + _receiving_data += bytes_transferred; + _receiving_size -= bytes_transferred; + + // check if current tran buf is used out + if (_receiving_size == 0 && !reset_tran_buf()) + { + close("out of memory"); + return; + } + + // release token + atomic_comp_swap(&_receive_token, TOKEN_FREE, TOKEN_LOCK); + + // trigger next receive + try_start_receive(); + + // process messages + while (!is_closed() && !received_messages.empty()) + { + const ReceivedItem& item = received_messages.front(); + on_received(item.message, item.meta_size, item.data_size); + received_messages.pop_front(); + } + } + + // Callback of "async_write_some()". + virtual void on_write_some( + const boost::system::error_code& error, + std::size_t bytes_transferred) + { + SOFA_PBRPC_FUNCTION_TRACE; + + if (error) + { +#if defined( LOG ) + LOG(ERROR) << "on_write_some(): " << RpcEndpointToString(_remote_endpoint) + << ": write error: " << error.message(); +#else + SLOG(ERROR, "on_write_some(): %s: write error: %s", + RpcEndpointToString(_remote_endpoint).c_str(), + error.message().c_str()); +#endif + + on_send_failed(RPC_ERROR_CHANNEL_BROKEN, _sending_message, _sending_cookie); + clear_sending_env(); + + close(error.message()); + return; + } + + _last_rw_ticks = _ticks; + _sent_size += bytes_transferred; + ++_total_sent_count; + _total_sent_size += bytes_transferred; + + if (static_cast(bytes_transferred) == _sending_size) + { + // seek to the next buf handle + if (_sending_message->Next( + reinterpret_cast(&_sending_data), + &_sending_size)) + { + // more buf to send + async_write_some(_sending_data, _sending_size); + } + else + { + // current message is completely sent + SCHECK_EQ(_sent_size, _sending_message->ByteCount()); + + // call hook function + on_sent(_sending_message, _sending_cookie); + clear_sending_env(); + + // release token + atomic_comp_swap(&_send_token, TOKEN_FREE, TOKEN_LOCK); + + // trigger next send + try_start_send(); + + // trigger next receive if it is server, because receiving operator + // in server may be hanged for pending buffer full. + if (_role_type == ROLE_TYPE_SERVER) + try_start_receive(); + } + } + else + { + // only sent part of the data + SCHECK_LT(static_cast(bytes_transferred), _sending_size); + + // start sending the remaining data + _sending_data += bytes_transferred; + _sending_size -= bytes_transferred; + async_write_some(_sending_data, _sending_size); + } + } + + // Put an item into back of the pending queue. + // + // @return false if the pending queue is full. + void put_into_pending_queue( + const ReadBufferPtr& message, + const SendCookie& cookie) + { + SOFA_PBRPC_FUNCTION_TRACE; + + ScopedLocker _(_pending_lock); + _pending_calls.push_back(PendingItem(message, cookie)); + ++_pending_message_count; + _pending_data_size += message->TotalCount(); + _pending_buffer_size += message->BlockCount() * TranBufPool::block_size(); + } + + // Insert an item into front of the pending queue. + // + // @return false if the pending queue is full. + void insert_into_pending_queue( + const ReadBufferPtr& message, + const SendCookie& cookie) + { + SOFA_PBRPC_FUNCTION_TRACE; + + _swapped_calls.push_back(PendingItem(message, cookie)); + ++_swapped_message_count; + _swapped_data_size += message->TotalCount(); + _swapped_buffer_size += message->BlockCount() * TranBufPool::block_size(); + } + + // Get an item from the pending queue. + // + // @return false if the pending queue is empty. + bool get_from_pending_queue( + ReadBufferPtr* message, + SendCookie* cookie) + { + SOFA_PBRPC_FUNCTION_TRACE; + + if (_swapped_calls.empty() && _pending_message_count > 0) + { + // swap from _pending_calls + ScopedLocker _(_pending_lock); + if (!_pending_calls.empty()) + { + _swapped_calls.swap(_pending_calls); + _swapped_message_count = _pending_message_count; + _swapped_data_size = _pending_data_size; + _swapped_buffer_size = _pending_buffer_size; + _pending_message_count = 0; + _pending_data_size = 0; + _pending_buffer_size = 0; + } + } + + if (!_swapped_calls.empty()) + { + // fetch the top one + *message = _swapped_calls.front().message; + *cookie = _swapped_calls.front().cookie; + _swapped_calls.pop_front(); + // update stats + --_swapped_message_count; + _swapped_data_size -= (*message)->TotalCount(); + _swapped_buffer_size -= (*message)->BlockCount() * TranBufPool::block_size(); + return true; + } + + // no message found + return false; + } + + // Try to start receiving messages. It will check that receiving is allowed, + // and try to acquire the reveive token. + // + // If failed, the receiving is ignored. + // If succeed, the token must be acquired. + bool try_start_receive() + { + SOFA_PBRPC_FUNCTION_TRACE; + + if (_receive_token == TOKEN_LOCK) + { + // no token + return false; + } + + if (_read_quota_token <= 0) + { + // last acquire quota failed + return false; + } + + if (_role_type == ROLE_TYPE_SERVER + && _pending_buffer_size > _max_pending_buffer_size) + { + // sending buffer full, should suspend receiving to wait + return false; + } + + bool started = false; + if (is_connected() + && atomic_comp_swap(&_receive_token, TOKEN_LOCK, TOKEN_FREE) == TOKEN_FREE) + { + SCHECK(_receiving_data != NULL); + SCHECK(_receiving_size > 0); + if((_read_quota_token = _flow_controller->acquire_read_quota(_receiving_size)) <= 0) + { + // no network quota + atomic_comp_swap(&_receive_token, TOKEN_FREE, TOKEN_LOCK); + } + else + { + // now start receive + async_read_some(_receiving_data, _receiving_size); + started = true; + } + } + return started; + } + + // Try to start sending a message. It will check that sending is allowed, + // and try to acquire the send token. + // + // If failed, the sending is ignored. + // If succeed, the token must be acquired. + bool try_start_send() + { + SOFA_PBRPC_FUNCTION_TRACE; + + if (_send_token == TOKEN_LOCK) + { + // no token + return false; + } + + if (_write_quota_token <= 0) + { + // last acquire quota failed + return false; + } + + bool started = false; + while (is_connected() + && atomic_comp_swap(&_send_token, TOKEN_LOCK, TOKEN_FREE) == TOKEN_FREE) + { + if (get_from_pending_queue(&_sending_message, &_sending_cookie)) + { + if (!on_sending(_sending_message, _sending_cookie)) + { + // need not send + on_send_failed(RPC_ERROR_REQUEST_CANCELED, _sending_message, _sending_cookie); + clear_sending_env(); + + atomic_comp_swap(&_send_token, TOKEN_FREE, TOKEN_LOCK); + } + else if ((_write_quota_token =_flow_controller->acquire_write_quota( + _sending_message->TotalCount())) <= 0) + { + // no network quota + insert_into_pending_queue(_sending_message, _sending_cookie); + clear_sending_env(); + + atomic_comp_swap(&_send_token, TOKEN_FREE, TOKEN_LOCK); + break; + } + else + { + // now send + _sent_size = 0; + bool ret = _sending_message->Next( + reinterpret_cast(&_sending_data), &_sending_size); + SCHECK(ret); + async_write_some(_sending_data, _sending_size); + started = true; + break; + } + } + else + { + // empty pending queue + atomic_comp_swap(&_send_token, TOKEN_FREE, TOKEN_LOCK); + break; + } + } + return started; + } + + // Process "data", split message, and store found messages. + // + // @return true if no error occured, and found messages are stored + // in "received_messages", may be empty. + // @return false if error occured, for example bad message stream. + class ReceivedItem; + bool split_and_process_message(char* data, int size, + std::deque* received_messages) + { + SOFA_PBRPC_FUNCTION_TRACE; + + while (size > 0) + { + if (!_receiving_header_identified) + { + int consumed; + int identify_result = identify_message_header(data, size, &consumed); + if (identify_result > 0) + { + _receiving_header_identified = true; + if (consumed == size) + { + // all the data is consumed by header + return true; + } + else + { + data += consumed; + size -= consumed; + } + } + else if (identify_result == 0) + { + // in-complete header + return true; + } + else // identify_result < 0 + { + return false; + } + } + + int64 message_size = _receiving_header.message_size; + if (_received_message_size + size < message_size) + { + // all the remaining data belongs to the in-complete message + _receiving_message->Append(BufHandle(_tran_buf, size, data - _tran_buf)); + _received_message_size += size; + return true; + } + + int64 consume_size = message_size - _received_message_size; + _receiving_message->Append(BufHandle(_tran_buf, consume_size, data - _tran_buf)); + received_messages->push_back(ReceivedItem(_receiving_message, + _receiving_header.meta_size, _receiving_header.data_size)); + reset_receiving_env(); + data += consume_size; + size -= consume_size; + } + + return true; + } + + // Identify a message header. + // + // @return 1 a header identified. The header is stored in "_receiving_header", + // @return 0 no header identified for incomplete data reason. All the data is + // consumed and copied into "_receiving_header". + // @return -1 the message stream is broken. + int identify_message_header(char* data, int size, int* consumed) + { + // copy the data into the correct position of the header + int header_size = static_cast(sizeof(_receiving_header)); + int copy_size = std::min(size, header_size - _received_header_size); + memcpy(reinterpret_cast(&_receiving_header) + _received_header_size, + data, copy_size); + _received_header_size += copy_size; + *consumed = copy_size; + + if (_received_header_size < header_size) + { + // in-complete header + return 0; + } + else // complete header + { + // check header magic str + if (!_receiving_header.CheckMagicString()) + { +#if defined( LOG ) + LOG(ERROR) << "identify_message_header(): " << RpcEndpointToString(_remote_endpoint) + << ": check magic string failed: " << _receiving_header.magic_str_value; +#else + SLOG(ERROR, "identify_message_header(): %s: check magic string failed: 0x%8x", + RpcEndpointToString(_remote_endpoint).c_str(), _receiving_header.magic_str_value); +#endif + return -1; + } + if (_receiving_header.meta_size + _receiving_header.data_size != _receiving_header.message_size) + { +#if defined( LOG ) + LOG(ERROR) << "identify_message_header(): " << RpcEndpointToString(_remote_endpoint) + << ": check size in header failed" + << ": meta_size=" << _receiving_header.meta_size + << ", data_size=" << _receiving_header.data_size + << ", message_size=" << _receiving_header.message_size; +#else + SLOG(ERROR, "identify_message_header(): %s: " + "check size in header failed: meta_size=%d, data_size=%lld, message_size=%lld", + RpcEndpointToString(_remote_endpoint).c_str(), + _receiving_header.meta_size, + _receiving_header.data_size, + _receiving_header.message_size); +#endif + return -1; + } + return 1; + } + } + + // Clear temp variables for sending message. + void clear_sending_env() + { + _sending_message.reset(); + _sending_cookie = SendCookie(); + _sent_size = 0; + _sending_data = NULL; + _sending_size = 0; + } + + // Reset temp variables for receiving message. + void reset_receiving_env() + { + _receiving_message.reset(new ReadBuffer()); + _received_message_size = 0; + _received_header_size = 0; + _receiving_header_identified = false; + } + + // Reset tran buf variables for receiving message. + bool reset_tran_buf() + { + if (_tran_buf != NULL) + { + // free old buf, in fact just decrease ref count + TranBufPool::free(_tran_buf); + _tran_buf = NULL; + } + + _tran_buf = reinterpret_cast(TranBufPool::malloc()); + if(_tran_buf == NULL) + { +#if defined( LOG ) + LOG(ERROR) << "reset_tran_buf(): " << RpcEndpointToString(_remote_endpoint) + << ": malloc buffer failed: out of memory"; +#else + SLOG(ERROR, "reset_tran_buf(): %s: malloc buffer failed: out of memory", + RpcEndpointToString(_remote_endpoint).c_str()); +#endif + return false; + } + _receiving_data = reinterpret_cast(_tran_buf); + _receiving_size = TranBufPool::block_size(); + return true; + } + +protected: + RoleType _role_type; + +private: + struct PendingItem + { + ReadBufferPtr message; + SendCookie cookie; + PendingItem(const ReadBufferPtr& _message, + const SendCookie& _cookie) + : message(_message) + , cookie(_cookie) {} + }; + + struct ReceivedItem + { + ReadBufferPtr message; + int meta_size; + int64 data_size; + ReceivedItem(const ReadBufferPtr& _message, + int _meta_size, + int64 _data_size) + : message(_message) + , meta_size(_meta_size) + , data_size(_data_size) {} + }; + + // TODO improve sync queue performance + volatile int _pending_message_count; + volatile int64 _pending_data_size; + volatile int64 _pending_buffer_size; + std::deque _pending_calls; + FastLock _pending_lock; + std::deque _swapped_calls; + volatile int _swapped_message_count; + volatile int64 _swapped_data_size; + volatile int64 _swapped_buffer_size; + + // flow control + FlowControllerPtr _flow_controller; + int64 _max_pending_buffer_size; + volatile int32 _read_quota_token; // <=0 means no quota + volatile int32 _write_quota_token; // <=0 means no quota + + // statistics + int64 _total_sent_count; + int64 _total_sent_size; + int64 _total_received_count; + int64 _total_received_size; + + // temp variables for sending message + ReadBufferPtr _sending_message; //current sending message + SendCookie _sending_cookie; // cookie of the message + int64 _sent_size; // current sent size of the message + const char* _sending_data; // current sending data, weak ptr + int _sending_size; // size of the current sending data + + // temp variables for receiving message + ReadBufferPtr _receiving_message; // current receiving message + int64 _received_message_size; // current received size of the message + RpcMessageHeader _receiving_header; + int _received_header_size; + bool _receiving_header_identified; + + // tran buf for reading data + char* _tran_buf; // strong ptr + char* _receiving_data; // weak ptr + int64 _receiving_size; + + // send and receive token + static const int TOKEN_FREE = 0; + static const int TOKEN_LOCK = 1; + volatile int _send_token; + volatile int _receive_token; +}; // class RpcMessageStream + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_RPC_MESSAGE_STREAM_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_meta.pb.cc b/src/sofa/pbrpc/rpc_meta.pb.cc new file mode 100644 index 0000000..cf302a2 --- /dev/null +++ b/src/sofa/pbrpc/rpc_meta.pb.cc @@ -0,0 +1,678 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "sofa/pbrpc/rpc_meta.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace sofa { +namespace pbrpc { + +namespace { + +const ::google::protobuf::Descriptor* RpcMeta_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RpcMeta_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* RpcMeta_Type_descriptor_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_sofa_2fpbrpc_2frpc_5fmeta_2eproto() { + protobuf_AddDesc_sofa_2fpbrpc_2frpc_5fmeta_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "sofa/pbrpc/rpc_meta.proto"); + GOOGLE_CHECK(file != NULL); + RpcMeta_descriptor_ = file->message_type(0); + static const int RpcMeta_offsets_[8] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RpcMeta, type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RpcMeta, sequence_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RpcMeta, method_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RpcMeta, failed_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RpcMeta, error_code_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RpcMeta, reason_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RpcMeta, compress_type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RpcMeta, expected_response_compress_type_), + }; + RpcMeta_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RpcMeta_descriptor_, + RpcMeta::default_instance_, + RpcMeta_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RpcMeta, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RpcMeta, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RpcMeta)); + RpcMeta_Type_descriptor_ = RpcMeta_descriptor_->enum_type(0); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_sofa_2fpbrpc_2frpc_5fmeta_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RpcMeta_descriptor_, &RpcMeta::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_sofa_2fpbrpc_2frpc_5fmeta_2eproto() { + delete RpcMeta::default_instance_; + delete RpcMeta_reflection_; +} + +void protobuf_AddDesc_sofa_2fpbrpc_2frpc_5fmeta_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::sofa::pbrpc::protobuf_AddDesc_sofa_2fpbrpc_2frpc_5foption_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\031sofa/pbrpc/rpc_meta.proto\022\nsofa.pbrpc\032" + "\033sofa/pbrpc/rpc_option.proto\"\246\002\n\007RpcMeta" + "\022&\n\004type\030\001 \002(\0162\030.sofa.pbrpc.RpcMeta.Type" + "\022\023\n\013sequence_id\030\002 \002(\004\022\016\n\006method\030d \001(\t\022\017\n" + "\006failed\030\310\001 \001(\010\022\023\n\nerror_code\030\311\001 \001(\005\022\017\n\006r" + "eason\030\312\001 \001(\t\0220\n\rcompress_type\030\254\002 \001(\0162\030.s" + "ofa.pbrpc.CompressType\022B\n\037expected_respo" + "nse_compress_type\030\255\002 \001(\0162\030.sofa.pbrpc.Co" + "mpressType\"!\n\004Type\022\013\n\007REQUEST\020\000\022\014\n\010RESPO" + "NSE\020\001", 365); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "sofa/pbrpc/rpc_meta.proto", &protobuf_RegisterTypes); + RpcMeta::default_instance_ = new RpcMeta(); + RpcMeta::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_sofa_2fpbrpc_2frpc_5fmeta_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_sofa_2fpbrpc_2frpc_5fmeta_2eproto { + StaticDescriptorInitializer_sofa_2fpbrpc_2frpc_5fmeta_2eproto() { + protobuf_AddDesc_sofa_2fpbrpc_2frpc_5fmeta_2eproto(); + } +} static_descriptor_initializer_sofa_2fpbrpc_2frpc_5fmeta_2eproto_; + + +// =================================================================== + +const ::google::protobuf::EnumDescriptor* RpcMeta_Type_descriptor() { + protobuf_AssignDescriptorsOnce(); + return RpcMeta_Type_descriptor_; +} +bool RpcMeta_Type_IsValid(int value) { + switch(value) { + case 0: + case 1: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const RpcMeta_Type RpcMeta::REQUEST; +const RpcMeta_Type RpcMeta::RESPONSE; +const RpcMeta_Type RpcMeta::Type_MIN; +const RpcMeta_Type RpcMeta::Type_MAX; +const int RpcMeta::Type_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int RpcMeta::kTypeFieldNumber; +const int RpcMeta::kSequenceIdFieldNumber; +const int RpcMeta::kMethodFieldNumber; +const int RpcMeta::kFailedFieldNumber; +const int RpcMeta::kErrorCodeFieldNumber; +const int RpcMeta::kReasonFieldNumber; +const int RpcMeta::kCompressTypeFieldNumber; +const int RpcMeta::kExpectedResponseCompressTypeFieldNumber; +#endif // !_MSC_VER + +RpcMeta::RpcMeta() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RpcMeta::InitAsDefaultInstance() { +} + +RpcMeta::RpcMeta(const RpcMeta& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RpcMeta::SharedCtor() { + _cached_size_ = 0; + type_ = 0; + sequence_id_ = GOOGLE_ULONGLONG(0); + method_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + failed_ = false; + error_code_ = 0; + reason_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + compress_type_ = 0; + expected_response_compress_type_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RpcMeta::~RpcMeta() { + SharedDtor(); +} + +void RpcMeta::SharedDtor() { + if (method_ != &::google::protobuf::internal::kEmptyString) { + delete method_; + } + if (reason_ != &::google::protobuf::internal::kEmptyString) { + delete reason_; + } + if (this != default_instance_) { + } +} + +void RpcMeta::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RpcMeta::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RpcMeta_descriptor_; +} + +const RpcMeta& RpcMeta::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_sofa_2fpbrpc_2frpc_5fmeta_2eproto(); return *default_instance_; +} + +RpcMeta* RpcMeta::default_instance_ = NULL; + +RpcMeta* RpcMeta::New() const { + return new RpcMeta; +} + +void RpcMeta::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + type_ = 0; + sequence_id_ = GOOGLE_ULONGLONG(0); + if (has_method()) { + if (method_ != &::google::protobuf::internal::kEmptyString) { + method_->clear(); + } + } + failed_ = false; + error_code_ = 0; + if (has_reason()) { + if (reason_ != &::google::protobuf::internal::kEmptyString) { + reason_->clear(); + } + } + compress_type_ = 0; + expected_response_compress_type_ = 0; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RpcMeta::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .sofa.pbrpc.RpcMeta.Type type = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::sofa::pbrpc::RpcMeta_Type_IsValid(value)) { + set_type(static_cast< ::sofa::pbrpc::RpcMeta_Type >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_sequence_id; + break; + } + + // required uint64 sequence_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_sequence_id: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &sequence_id_))); + set_has_sequence_id(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(802)) goto parse_method; + break; + } + + // optional string method = 100; + case 100: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_method: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_method())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->method().data(), this->method().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(1600)) goto parse_failed; + break; + } + + // optional bool failed = 200; + case 200: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_failed: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &failed_))); + set_has_failed(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(1608)) goto parse_error_code; + break; + } + + // optional int32 error_code = 201; + case 201: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_error_code: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &error_code_))); + set_has_error_code(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(1618)) goto parse_reason; + break; + } + + // optional string reason = 202; + case 202: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_reason: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_reason())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->reason().data(), this->reason().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(2400)) goto parse_compress_type; + break; + } + + // optional .sofa.pbrpc.CompressType compress_type = 300; + case 300: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_compress_type: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (sofa::pbrpc::CompressType_IsValid(value)) { + set_compress_type(static_cast< sofa::pbrpc::CompressType >(value)); + } else { + mutable_unknown_fields()->AddVarint(300, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(2408)) goto parse_expected_response_compress_type; + break; + } + + // optional .sofa.pbrpc.CompressType expected_response_compress_type = 301; + case 301: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_expected_response_compress_type: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (sofa::pbrpc::CompressType_IsValid(value)) { + set_expected_response_compress_type(static_cast< sofa::pbrpc::CompressType >(value)); + } else { + mutable_unknown_fields()->AddVarint(301, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void RpcMeta::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .sofa.pbrpc.RpcMeta.Type type = 1; + if (has_type()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->type(), output); + } + + // required uint64 sequence_id = 2; + if (has_sequence_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->sequence_id(), output); + } + + // optional string method = 100; + if (has_method()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->method().data(), this->method().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 100, this->method(), output); + } + + // optional bool failed = 200; + if (has_failed()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(200, this->failed(), output); + } + + // optional int32 error_code = 201; + if (has_error_code()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(201, this->error_code(), output); + } + + // optional string reason = 202; + if (has_reason()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->reason().data(), this->reason().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 202, this->reason(), output); + } + + // optional .sofa.pbrpc.CompressType compress_type = 300; + if (has_compress_type()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 300, this->compress_type(), output); + } + + // optional .sofa.pbrpc.CompressType expected_response_compress_type = 301; + if (has_expected_response_compress_type()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 301, this->expected_response_compress_type(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RpcMeta::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .sofa.pbrpc.RpcMeta.Type type = 1; + if (has_type()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->type(), target); + } + + // required uint64 sequence_id = 2; + if (has_sequence_id()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(2, this->sequence_id(), target); + } + + // optional string method = 100; + if (has_method()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->method().data(), this->method().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 100, this->method(), target); + } + + // optional bool failed = 200; + if (has_failed()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(200, this->failed(), target); + } + + // optional int32 error_code = 201; + if (has_error_code()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(201, this->error_code(), target); + } + + // optional string reason = 202; + if (has_reason()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->reason().data(), this->reason().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 202, this->reason(), target); + } + + // optional .sofa.pbrpc.CompressType compress_type = 300; + if (has_compress_type()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 300, this->compress_type(), target); + } + + // optional .sofa.pbrpc.CompressType expected_response_compress_type = 301; + if (has_expected_response_compress_type()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 301, this->expected_response_compress_type(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RpcMeta::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .sofa.pbrpc.RpcMeta.Type type = 1; + if (has_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->type()); + } + + // required uint64 sequence_id = 2; + if (has_sequence_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->sequence_id()); + } + + // optional string method = 100; + if (has_method()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->method()); + } + + // optional bool failed = 200; + if (has_failed()) { + total_size += 2 + 1; + } + + // optional int32 error_code = 201; + if (has_error_code()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->error_code()); + } + + // optional string reason = 202; + if (has_reason()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->reason()); + } + + // optional .sofa.pbrpc.CompressType compress_type = 300; + if (has_compress_type()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->compress_type()); + } + + // optional .sofa.pbrpc.CompressType expected_response_compress_type = 301; + if (has_expected_response_compress_type()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->expected_response_compress_type()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RpcMeta::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RpcMeta* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RpcMeta::MergeFrom(const RpcMeta& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_type()) { + set_type(from.type()); + } + if (from.has_sequence_id()) { + set_sequence_id(from.sequence_id()); + } + if (from.has_method()) { + set_method(from.method()); + } + if (from.has_failed()) { + set_failed(from.failed()); + } + if (from.has_error_code()) { + set_error_code(from.error_code()); + } + if (from.has_reason()) { + set_reason(from.reason()); + } + if (from.has_compress_type()) { + set_compress_type(from.compress_type()); + } + if (from.has_expected_response_compress_type()) { + set_expected_response_compress_type(from.expected_response_compress_type()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RpcMeta::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RpcMeta::CopyFrom(const RpcMeta& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RpcMeta::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void RpcMeta::Swap(RpcMeta* other) { + if (other != this) { + std::swap(type_, other->type_); + std::swap(sequence_id_, other->sequence_id_); + std::swap(method_, other->method_); + std::swap(failed_, other->failed_); + std::swap(error_code_, other->error_code_); + std::swap(reason_, other->reason_); + std::swap(compress_type_, other->compress_type_); + std::swap(expected_response_compress_type_, other->expected_response_compress_type_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RpcMeta::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RpcMeta_descriptor_; + metadata.reflection = RpcMeta_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace pbrpc +} // namespace sofa + +// @@protoc_insertion_point(global_scope) diff --git a/src/sofa/pbrpc/rpc_meta.pb.h b/src/sofa/pbrpc/rpc_meta.pb.h new file mode 100644 index 0000000..7146022 --- /dev/null +++ b/src/sofa/pbrpc/rpc_meta.pb.h @@ -0,0 +1,521 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: sofa/pbrpc/rpc_meta.proto + +#ifndef PROTOBUF_sofa_2fpbrpc_2frpc_5fmeta_2eproto__INCLUDED +#define PROTOBUF_sofa_2fpbrpc_2frpc_5fmeta_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2004000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2004001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include "sofa/pbrpc/rpc_option.pb.h" +// @@protoc_insertion_point(includes) + +namespace sofa { +namespace pbrpc { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_sofa_2fpbrpc_2frpc_5fmeta_2eproto(); +void protobuf_AssignDesc_sofa_2fpbrpc_2frpc_5fmeta_2eproto(); +void protobuf_ShutdownFile_sofa_2fpbrpc_2frpc_5fmeta_2eproto(); + +class RpcMeta; + +enum RpcMeta_Type { + RpcMeta_Type_REQUEST = 0, + RpcMeta_Type_RESPONSE = 1 +}; +bool RpcMeta_Type_IsValid(int value); +const RpcMeta_Type RpcMeta_Type_Type_MIN = RpcMeta_Type_REQUEST; +const RpcMeta_Type RpcMeta_Type_Type_MAX = RpcMeta_Type_RESPONSE; +const int RpcMeta_Type_Type_ARRAYSIZE = RpcMeta_Type_Type_MAX + 1; + +const ::google::protobuf::EnumDescriptor* RpcMeta_Type_descriptor(); +inline const ::std::string& RpcMeta_Type_Name(RpcMeta_Type value) { + return ::google::protobuf::internal::NameOfEnum( + RpcMeta_Type_descriptor(), value); +} +inline bool RpcMeta_Type_Parse( + const ::std::string& name, RpcMeta_Type* value) { + return ::google::protobuf::internal::ParseNamedEnum( + RpcMeta_Type_descriptor(), name, value); +} +// =================================================================== + +class RpcMeta : public ::google::protobuf::Message { + public: + RpcMeta(); + virtual ~RpcMeta(); + + RpcMeta(const RpcMeta& from); + + inline RpcMeta& operator=(const RpcMeta& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RpcMeta& default_instance(); + + void Swap(RpcMeta* other); + + // implements Message ---------------------------------------------- + + RpcMeta* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RpcMeta& from); + void MergeFrom(const RpcMeta& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef RpcMeta_Type Type; + static const Type REQUEST = RpcMeta_Type_REQUEST; + static const Type RESPONSE = RpcMeta_Type_RESPONSE; + static inline bool Type_IsValid(int value) { + return RpcMeta_Type_IsValid(value); + } + static const Type Type_MIN = + RpcMeta_Type_Type_MIN; + static const Type Type_MAX = + RpcMeta_Type_Type_MAX; + static const int Type_ARRAYSIZE = + RpcMeta_Type_Type_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + Type_descriptor() { + return RpcMeta_Type_descriptor(); + } + static inline const ::std::string& Type_Name(Type value) { + return RpcMeta_Type_Name(value); + } + static inline bool Type_Parse(const ::std::string& name, + Type* value) { + return RpcMeta_Type_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // required .sofa.pbrpc.RpcMeta.Type type = 1; + inline bool has_type() const; + inline void clear_type(); + static const int kTypeFieldNumber = 1; + inline ::sofa::pbrpc::RpcMeta_Type type() const; + inline void set_type(::sofa::pbrpc::RpcMeta_Type value); + + // required uint64 sequence_id = 2; + inline bool has_sequence_id() const; + inline void clear_sequence_id(); + static const int kSequenceIdFieldNumber = 2; + inline ::google::protobuf::uint64 sequence_id() const; + inline void set_sequence_id(::google::protobuf::uint64 value); + + // optional string method = 100; + inline bool has_method() const; + inline void clear_method(); + static const int kMethodFieldNumber = 100; + inline const ::std::string& method() const; + inline void set_method(const ::std::string& value); + inline void set_method(const char* value); + inline void set_method(const char* value, size_t size); + inline ::std::string* mutable_method(); + inline ::std::string* release_method(); + + // optional bool failed = 200; + inline bool has_failed() const; + inline void clear_failed(); + static const int kFailedFieldNumber = 200; + inline bool failed() const; + inline void set_failed(bool value); + + // optional int32 error_code = 201; + inline bool has_error_code() const; + inline void clear_error_code(); + static const int kErrorCodeFieldNumber = 201; + inline ::google::protobuf::int32 error_code() const; + inline void set_error_code(::google::protobuf::int32 value); + + // optional string reason = 202; + inline bool has_reason() const; + inline void clear_reason(); + static const int kReasonFieldNumber = 202; + inline const ::std::string& reason() const; + inline void set_reason(const ::std::string& value); + inline void set_reason(const char* value); + inline void set_reason(const char* value, size_t size); + inline ::std::string* mutable_reason(); + inline ::std::string* release_reason(); + + // optional .sofa.pbrpc.CompressType compress_type = 300; + inline bool has_compress_type() const; + inline void clear_compress_type(); + static const int kCompressTypeFieldNumber = 300; + inline sofa::pbrpc::CompressType compress_type() const; + inline void set_compress_type(sofa::pbrpc::CompressType value); + + // optional .sofa.pbrpc.CompressType expected_response_compress_type = 301; + inline bool has_expected_response_compress_type() const; + inline void clear_expected_response_compress_type(); + static const int kExpectedResponseCompressTypeFieldNumber = 301; + inline sofa::pbrpc::CompressType expected_response_compress_type() const; + inline void set_expected_response_compress_type(sofa::pbrpc::CompressType value); + + // @@protoc_insertion_point(class_scope:sofa.pbrpc.RpcMeta) + private: + inline void set_has_type(); + inline void clear_has_type(); + inline void set_has_sequence_id(); + inline void clear_has_sequence_id(); + inline void set_has_method(); + inline void clear_has_method(); + inline void set_has_failed(); + inline void clear_has_failed(); + inline void set_has_error_code(); + inline void clear_has_error_code(); + inline void set_has_reason(); + inline void clear_has_reason(); + inline void set_has_compress_type(); + inline void clear_has_compress_type(); + inline void set_has_expected_response_compress_type(); + inline void clear_has_expected_response_compress_type(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint64 sequence_id_; + int type_; + bool failed_; + ::std::string* method_; + ::std::string* reason_; + ::google::protobuf::int32 error_code_; + int compress_type_; + int expected_response_compress_type_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(8 + 31) / 32]; + + friend void protobuf_AddDesc_sofa_2fpbrpc_2frpc_5fmeta_2eproto(); + friend void protobuf_AssignDesc_sofa_2fpbrpc_2frpc_5fmeta_2eproto(); + friend void protobuf_ShutdownFile_sofa_2fpbrpc_2frpc_5fmeta_2eproto(); + + void InitAsDefaultInstance(); + static RpcMeta* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// RpcMeta + +// required .sofa.pbrpc.RpcMeta.Type type = 1; +inline bool RpcMeta::has_type() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void RpcMeta::set_has_type() { + _has_bits_[0] |= 0x00000001u; +} +inline void RpcMeta::clear_has_type() { + _has_bits_[0] &= ~0x00000001u; +} +inline void RpcMeta::clear_type() { + type_ = 0; + clear_has_type(); +} +inline ::sofa::pbrpc::RpcMeta_Type RpcMeta::type() const { + return static_cast< ::sofa::pbrpc::RpcMeta_Type >(type_); +} +inline void RpcMeta::set_type(::sofa::pbrpc::RpcMeta_Type value) { + GOOGLE_DCHECK(::sofa::pbrpc::RpcMeta_Type_IsValid(value)); + set_has_type(); + type_ = value; +} + +// required uint64 sequence_id = 2; +inline bool RpcMeta::has_sequence_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void RpcMeta::set_has_sequence_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void RpcMeta::clear_has_sequence_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void RpcMeta::clear_sequence_id() { + sequence_id_ = GOOGLE_ULONGLONG(0); + clear_has_sequence_id(); +} +inline ::google::protobuf::uint64 RpcMeta::sequence_id() const { + return sequence_id_; +} +inline void RpcMeta::set_sequence_id(::google::protobuf::uint64 value) { + set_has_sequence_id(); + sequence_id_ = value; +} + +// optional string method = 100; +inline bool RpcMeta::has_method() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void RpcMeta::set_has_method() { + _has_bits_[0] |= 0x00000004u; +} +inline void RpcMeta::clear_has_method() { + _has_bits_[0] &= ~0x00000004u; +} +inline void RpcMeta::clear_method() { + if (method_ != &::google::protobuf::internal::kEmptyString) { + method_->clear(); + } + clear_has_method(); +} +inline const ::std::string& RpcMeta::method() const { + return *method_; +} +inline void RpcMeta::set_method(const ::std::string& value) { + set_has_method(); + if (method_ == &::google::protobuf::internal::kEmptyString) { + method_ = new ::std::string; + } + method_->assign(value); +} +inline void RpcMeta::set_method(const char* value) { + set_has_method(); + if (method_ == &::google::protobuf::internal::kEmptyString) { + method_ = new ::std::string; + } + method_->assign(value); +} +inline void RpcMeta::set_method(const char* value, size_t size) { + set_has_method(); + if (method_ == &::google::protobuf::internal::kEmptyString) { + method_ = new ::std::string; + } + method_->assign(reinterpret_cast(value), size); +} +inline ::std::string* RpcMeta::mutable_method() { + set_has_method(); + if (method_ == &::google::protobuf::internal::kEmptyString) { + method_ = new ::std::string; + } + return method_; +} +inline ::std::string* RpcMeta::release_method() { + clear_has_method(); + if (method_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = method_; + method_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// optional bool failed = 200; +inline bool RpcMeta::has_failed() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void RpcMeta::set_has_failed() { + _has_bits_[0] |= 0x00000008u; +} +inline void RpcMeta::clear_has_failed() { + _has_bits_[0] &= ~0x00000008u; +} +inline void RpcMeta::clear_failed() { + failed_ = false; + clear_has_failed(); +} +inline bool RpcMeta::failed() const { + return failed_; +} +inline void RpcMeta::set_failed(bool value) { + set_has_failed(); + failed_ = value; +} + +// optional int32 error_code = 201; +inline bool RpcMeta::has_error_code() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void RpcMeta::set_has_error_code() { + _has_bits_[0] |= 0x00000010u; +} +inline void RpcMeta::clear_has_error_code() { + _has_bits_[0] &= ~0x00000010u; +} +inline void RpcMeta::clear_error_code() { + error_code_ = 0; + clear_has_error_code(); +} +inline ::google::protobuf::int32 RpcMeta::error_code() const { + return error_code_; +} +inline void RpcMeta::set_error_code(::google::protobuf::int32 value) { + set_has_error_code(); + error_code_ = value; +} + +// optional string reason = 202; +inline bool RpcMeta::has_reason() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void RpcMeta::set_has_reason() { + _has_bits_[0] |= 0x00000020u; +} +inline void RpcMeta::clear_has_reason() { + _has_bits_[0] &= ~0x00000020u; +} +inline void RpcMeta::clear_reason() { + if (reason_ != &::google::protobuf::internal::kEmptyString) { + reason_->clear(); + } + clear_has_reason(); +} +inline const ::std::string& RpcMeta::reason() const { + return *reason_; +} +inline void RpcMeta::set_reason(const ::std::string& value) { + set_has_reason(); + if (reason_ == &::google::protobuf::internal::kEmptyString) { + reason_ = new ::std::string; + } + reason_->assign(value); +} +inline void RpcMeta::set_reason(const char* value) { + set_has_reason(); + if (reason_ == &::google::protobuf::internal::kEmptyString) { + reason_ = new ::std::string; + } + reason_->assign(value); +} +inline void RpcMeta::set_reason(const char* value, size_t size) { + set_has_reason(); + if (reason_ == &::google::protobuf::internal::kEmptyString) { + reason_ = new ::std::string; + } + reason_->assign(reinterpret_cast(value), size); +} +inline ::std::string* RpcMeta::mutable_reason() { + set_has_reason(); + if (reason_ == &::google::protobuf::internal::kEmptyString) { + reason_ = new ::std::string; + } + return reason_; +} +inline ::std::string* RpcMeta::release_reason() { + clear_has_reason(); + if (reason_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = reason_; + reason_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// optional .sofa.pbrpc.CompressType compress_type = 300; +inline bool RpcMeta::has_compress_type() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void RpcMeta::set_has_compress_type() { + _has_bits_[0] |= 0x00000040u; +} +inline void RpcMeta::clear_has_compress_type() { + _has_bits_[0] &= ~0x00000040u; +} +inline void RpcMeta::clear_compress_type() { + compress_type_ = 0; + clear_has_compress_type(); +} +inline sofa::pbrpc::CompressType RpcMeta::compress_type() const { + return static_cast< sofa::pbrpc::CompressType >(compress_type_); +} +inline void RpcMeta::set_compress_type(sofa::pbrpc::CompressType value) { + GOOGLE_DCHECK(sofa::pbrpc::CompressType_IsValid(value)); + set_has_compress_type(); + compress_type_ = value; +} + +// optional .sofa.pbrpc.CompressType expected_response_compress_type = 301; +inline bool RpcMeta::has_expected_response_compress_type() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void RpcMeta::set_has_expected_response_compress_type() { + _has_bits_[0] |= 0x00000080u; +} +inline void RpcMeta::clear_has_expected_response_compress_type() { + _has_bits_[0] &= ~0x00000080u; +} +inline void RpcMeta::clear_expected_response_compress_type() { + expected_response_compress_type_ = 0; + clear_has_expected_response_compress_type(); +} +inline sofa::pbrpc::CompressType RpcMeta::expected_response_compress_type() const { + return static_cast< sofa::pbrpc::CompressType >(expected_response_compress_type_); +} +inline void RpcMeta::set_expected_response_compress_type(sofa::pbrpc::CompressType value) { + GOOGLE_DCHECK(sofa::pbrpc::CompressType_IsValid(value)); + set_has_expected_response_compress_type(); + expected_response_compress_type_ = value; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace pbrpc +} // namespace sofa + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::sofa::pbrpc::RpcMeta_Type>() { + return ::sofa::pbrpc::RpcMeta_Type_descriptor(); +} + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_sofa_2fpbrpc_2frpc_5fmeta_2eproto__INCLUDED diff --git a/src/sofa/pbrpc/rpc_meta.proto b/src/sofa/pbrpc/rpc_meta.proto new file mode 100644 index 0000000..b5b3751 --- /dev/null +++ b/src/sofa/pbrpc/rpc_meta.proto @@ -0,0 +1,39 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +import "sofa/pbrpc/rpc_option.proto"; + +package sofa.pbrpc; + +message RpcMeta { + enum Type { + REQUEST = 0; + RESPONSE = 1; + }; + + // Required fields for both request and response, tag starts from 1. + required Type type = 1; + required uint64 sequence_id = 2; + + // Field for request type, tag starts from 100. + // The fully-qualified name of the method, scope delimited by periods. + // It includes the full name of service. + // For example: "test.HelloService.GreetMethod" + optional string method = 100; + + // Field for response type, tag starts from 200. + // If the request is failed. + optional bool failed = 200; + // Set the error code if failed. + optional int32 error_code = 201; + // Set the reason if failed. + optional string reason = 202; + + // Set the request/response compress type. + optional CompressType compress_type = 300; + // Set the response compress type of user expected. + optional CompressType expected_response_compress_type = 301; +} diff --git a/src/sofa/pbrpc/rpc_option.pb.cc b/src/sofa/pbrpc/rpc_option.pb.cc new file mode 100644 index 0000000..e70f169 --- /dev/null +++ b/src/sofa/pbrpc/rpc_option.pb.cc @@ -0,0 +1,135 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "sofa/pbrpc/rpc_option.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace sofa { +namespace pbrpc { + +namespace { + +const ::google::protobuf::EnumDescriptor* CompressType_descriptor_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_sofa_2fpbrpc_2frpc_5foption_2eproto() { + protobuf_AddDesc_sofa_2fpbrpc_2frpc_5foption_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "sofa/pbrpc/rpc_option.proto"); + GOOGLE_CHECK(file != NULL); + CompressType_descriptor_ = file->enum_type(0); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_sofa_2fpbrpc_2frpc_5foption_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); +} + +} // namespace + +void protobuf_ShutdownFile_sofa_2fpbrpc_2frpc_5foption_2eproto() { +} + +void protobuf_AddDesc_sofa_2fpbrpc_2frpc_5foption_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\033sofa/pbrpc/rpc_option.proto\022\nsofa.pbrp" + "c\032 google/protobuf/descriptor.proto*}\n\014C" + "ompressType\022\024\n\020CompressTypeNone\020\000\022\024\n\020Com" + "pressTypeGzip\020\001\022\024\n\020CompressTypeZlib\020\002\022\026\n" + "\022CompressTypeSnappy\020\003\022\023\n\017CompressTypeLZ4" + "\020\004:A\n\017service_timeout\022\037.google.protobuf." + "ServiceOptions\030\240\234\001 \001(\003:\00510000:8\n\016method_" + "timeout\022\036.google.protobuf.MethodOptions\030" + "\240\234\001 \001(\003:k\n\025request_compress_type\022\036.googl" + "e.protobuf.MethodOptions\030\241\234\001 \001(\0162\030.sofa." + "pbrpc.CompressType:\020CompressTypeNone:l\n\026" + "response_compress_type\022\036.google.protobuf" + ".MethodOptions\030\242\234\001 \001(\0162\030.sofa.pbrpc.Comp" + "ressType:\020CompressTypeNone", 546); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "sofa/pbrpc/rpc_option.proto", &protobuf_RegisterTypes); + ::google::protobuf::internal::ExtensionSet::RegisterExtension( + &::google::protobuf::ServiceOptions::default_instance(), + 20000, 3, false, false); + ::google::protobuf::internal::ExtensionSet::RegisterExtension( + &::google::protobuf::MethodOptions::default_instance(), + 20000, 3, false, false); + ::google::protobuf::internal::ExtensionSet::RegisterEnumExtension( + &::google::protobuf::MethodOptions::default_instance(), + 20001, 14, false, false, + &sofa::pbrpc::CompressType_IsValid); + ::google::protobuf::internal::ExtensionSet::RegisterEnumExtension( + &::google::protobuf::MethodOptions::default_instance(), + 20002, 14, false, false, + &sofa::pbrpc::CompressType_IsValid); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_sofa_2fpbrpc_2frpc_5foption_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_sofa_2fpbrpc_2frpc_5foption_2eproto { + StaticDescriptorInitializer_sofa_2fpbrpc_2frpc_5foption_2eproto() { + protobuf_AddDesc_sofa_2fpbrpc_2frpc_5foption_2eproto(); + } +} static_descriptor_initializer_sofa_2fpbrpc_2frpc_5foption_2eproto_; + +const ::google::protobuf::EnumDescriptor* CompressType_descriptor() { + protobuf_AssignDescriptorsOnce(); + return CompressType_descriptor_; +} +bool CompressType_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + case 3: + case 4: + return true; + default: + return false; + } +} + +::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::ServiceOptions, + ::google::protobuf::internal::PrimitiveTypeTraits< ::google::protobuf::int64 >, 3, false > + service_timeout(kServiceTimeoutFieldNumber, GOOGLE_LONGLONG(10000)); +::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MethodOptions, + ::google::protobuf::internal::PrimitiveTypeTraits< ::google::protobuf::int64 >, 3, false > + method_timeout(kMethodTimeoutFieldNumber, GOOGLE_LONGLONG(0)); +::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MethodOptions, + ::google::protobuf::internal::EnumTypeTraits< sofa::pbrpc::CompressType, sofa::pbrpc::CompressType_IsValid>, 14, false > + request_compress_type(kRequestCompressTypeFieldNumber, static_cast< sofa::pbrpc::CompressType >(0)); +::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MethodOptions, + ::google::protobuf::internal::EnumTypeTraits< sofa::pbrpc::CompressType, sofa::pbrpc::CompressType_IsValid>, 14, false > + response_compress_type(kResponseCompressTypeFieldNumber, static_cast< sofa::pbrpc::CompressType >(0)); + +// @@protoc_insertion_point(namespace_scope) + +} // namespace pbrpc +} // namespace sofa + +// @@protoc_insertion_point(global_scope) diff --git a/src/sofa/pbrpc/rpc_option.pb.h b/src/sofa/pbrpc/rpc_option.pb.h new file mode 100644 index 0000000..7fbb315 --- /dev/null +++ b/src/sofa/pbrpc/rpc_option.pb.h @@ -0,0 +1,105 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: sofa/pbrpc/rpc_option.proto + +#ifndef PROTOBUF_sofa_2fpbrpc_2frpc_5foption_2eproto__INCLUDED +#define PROTOBUF_sofa_2fpbrpc_2frpc_5foption_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2004000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2004001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include "google/protobuf/descriptor.pb.h" +// @@protoc_insertion_point(includes) + +namespace sofa { +namespace pbrpc { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_sofa_2fpbrpc_2frpc_5foption_2eproto(); +void protobuf_AssignDesc_sofa_2fpbrpc_2frpc_5foption_2eproto(); +void protobuf_ShutdownFile_sofa_2fpbrpc_2frpc_5foption_2eproto(); + + +enum CompressType { + CompressTypeNone = 0, + CompressTypeGzip = 1, + CompressTypeZlib = 2, + CompressTypeSnappy = 3, + CompressTypeLZ4 = 4 +}; +bool CompressType_IsValid(int value); +const CompressType CompressType_MIN = CompressTypeNone; +const CompressType CompressType_MAX = CompressTypeLZ4; +const int CompressType_ARRAYSIZE = CompressType_MAX + 1; + +const ::google::protobuf::EnumDescriptor* CompressType_descriptor(); +inline const ::std::string& CompressType_Name(CompressType value) { + return ::google::protobuf::internal::NameOfEnum( + CompressType_descriptor(), value); +} +inline bool CompressType_Parse( + const ::std::string& name, CompressType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + CompressType_descriptor(), name, value); +} +// =================================================================== + + +// =================================================================== + +static const int kServiceTimeoutFieldNumber = 20000; +extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::ServiceOptions, + ::google::protobuf::internal::PrimitiveTypeTraits< ::google::protobuf::int64 >, 3, false > + service_timeout; +static const int kMethodTimeoutFieldNumber = 20000; +extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MethodOptions, + ::google::protobuf::internal::PrimitiveTypeTraits< ::google::protobuf::int64 >, 3, false > + method_timeout; +static const int kRequestCompressTypeFieldNumber = 20001; +extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MethodOptions, + ::google::protobuf::internal::EnumTypeTraits< sofa::pbrpc::CompressType, sofa::pbrpc::CompressType_IsValid>, 14, false > + request_compress_type; +static const int kResponseCompressTypeFieldNumber = 20002; +extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MethodOptions, + ::google::protobuf::internal::EnumTypeTraits< sofa::pbrpc::CompressType, sofa::pbrpc::CompressType_IsValid>, 14, false > + response_compress_type; + +// =================================================================== + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace pbrpc +} // namespace sofa + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> +inline const EnumDescriptor* GetEnumDescriptor< sofa::pbrpc::CompressType>() { + return sofa::pbrpc::CompressType_descriptor(); +} + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_sofa_2fpbrpc_2frpc_5foption_2eproto__INCLUDED diff --git a/src/sofa/pbrpc/rpc_option.proto b/src/sofa/pbrpc/rpc_option.proto new file mode 100644 index 0000000..e5a8ab3 --- /dev/null +++ b/src/sofa/pbrpc/rpc_option.proto @@ -0,0 +1,33 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +import "google/protobuf/descriptor.proto"; + +package sofa.pbrpc; + +extend google.protobuf.ServiceOptions { + // Timeout in milliseconds, at service level. + optional int64 service_timeout = 20000 [default = 10000]; +} + +enum CompressType { + CompressTypeNone = 0; + CompressTypeGzip = 1; + CompressTypeZlib = 2; + CompressTypeSnappy = 3; + CompressTypeLZ4 = 4; +} + +extend google.protobuf.MethodOptions { + // Timeout in milliseconds, at method level. + // It doesn't have a default value as method without method_timeout set would + // use service_timeout. + optional int64 method_timeout = 20000; + + // Compress type. + optional CompressType request_compress_type = 20001 [default = CompressTypeNone]; + optional CompressType response_compress_type = 20002 [default = CompressTypeNone]; +} diff --git a/src/sofa/pbrpc/rpc_server.cc b/src/sofa/pbrpc/rpc_server.cc new file mode 100644 index 0000000..5d02d17 --- /dev/null +++ b/src/sofa/pbrpc/rpc_server.cc @@ -0,0 +1,84 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include +#include + +#include +#include + +namespace sofa { +namespace pbrpc { + +RpcServer::RpcServer(const RpcServerOptions& options, EventHandler* handler) + : _impl(new RpcServerImpl(options, handler)) +{ +} + +RpcServer::~RpcServer() +{ + Stop(); +} + +bool RpcServer::Start(const std::string& server_address) +{ + return _impl->Start(server_address); +} + +void RpcServer::Stop() +{ + _impl->Stop(); +} + +static volatile bool s_quit = false; +static void SignalIntHandler(int /*sig*/) +{ + s_quit = true; +} +int RpcServer::Run() +{ + signal(SIGINT, SignalIntHandler); + signal(SIGTERM, SignalIntHandler); + while (!s_quit) { + sleep(1); + } + return 0; +} + +RpcServerOptions RpcServer::GetOptions() +{ + return _impl->GetOptions(); +} + +void RpcServer::ResetOptions(const RpcServerOptions& options) +{ + _impl->ResetOptions(options); +} + +bool RpcServer::RegisterService(google::protobuf::Service* service, bool take_ownership) +{ + return _impl->RegisterService(service, take_ownership); +} + +int RpcServer::ServiceCount() +{ + return _impl->ServiceCount(); +} + +int RpcServer::ConnectionCount() +{ + return _impl->ConnectionCount(); +} + +bool RpcServer::IsListening() +{ + return _impl->IsListening(); +} + +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_server.h b/src/sofa/pbrpc/rpc_server.h new file mode 100644 index 0000000..8f76e04 --- /dev/null +++ b/src/sofa/pbrpc/rpc_server.h @@ -0,0 +1,182 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_RPC_SERVER_H_ +#define _SOFA_PBRPC_RPC_SERVER_H_ + +#include + +#include +#include +#include + +namespace sofa { +namespace pbrpc { + +// Defined in other files. +class RpcServerImpl; + +struct RpcServerOptions { + int work_thread_num; // thread count for network handing and service processing, default 8. + + int keep_alive_time; // keep alive time of idle connections. + // idle connections will be closed if no read/write for this time. + // in seconds, should >= -1, -1 means for ever, default 65. + + int max_pending_buffer_size; // max buffer size of the pending send queue for one connection. + // in MB, should >= 0, 0 means no buffer, default 2. + + // Network throughput limit. + // The network bandwidth is shared by all connections: + // * busy connections get more bandwidth. + // * the total bandwidth of all connections will not exceed the limit. + int max_throughput_in; // max network in throughput for all connections. + // in MB/s, should >= -1, -1 means no limit, default -1. + int max_throughput_out; // max network out throughput for all connections. + // in MB/s, should >= -1, -1 means no limit, default -1. + + bool disable_builtin_services; // If disable builtin services, including health service, list + // service, status service, and so on. Default false. + bool disable_list_service; // If disable the list service, which would public your service + // protobuf descriptor. Default false. + + // Thread init function called at starting of each work thread. + // This closure should be a permanent closure created and destroyed by user. + // Default is NULL, means no init function. + // Return false if init failed. + // If any init function returns false, then the server will start failed. + ExtClosure* work_thread_init_func; + + // Thread destroy function called at ending of each work thread (even if init failed). + // This closure should be a permanent closure created and destroyed by user. + // Default is NULL, means no destroy function. + ExtClosure* work_thread_dest_func; + + RpcServerOptions() + : work_thread_num(8) + , keep_alive_time(65) + , max_pending_buffer_size(2) + , max_throughput_in(-1) + , max_throughput_out(-1) + , disable_builtin_services(false) + , disable_list_service(false) + , work_thread_init_func(NULL) + , work_thread_dest_func(NULL) + {} +}; + +class RpcServer +{ +public: + class EventHandler { + public: + virtual ~EventHandler() {} + + // This function is used to notify that some error has ocurred when accepting connections. + // The reason is passed by "error_code" and "error_text". If needed, the listener may be + // restarted to recover to usable state. + // + // The "error_code" may be: + // RPC_ERROR_TOO_MANY_OPEN_FILES + // RPC_ERROR_UNKNOWN + virtual void NotifyAcceptFailed(RpcErrorCode error_code, const std::string& error_text) = 0; + }; + +public: + // Constructor. + // @param options The rpc server options. + // @param handler The event handler. It will be taken overby the rpc server and will be + // deleted when the server destroys. + explicit RpcServer(const RpcServerOptions& options = RpcServerOptions(), + EventHandler* handler = NULL); + virtual ~RpcServer(); + + // Start the server, and listen on the "server_address". If succeed started + // and listened, return true. + bool Start(const std::string& server_address); + + // Stop the server. + void Stop(); + + // Wait the server run until catched signal SIGINT or SIGTERM. + // Returns exit code of process. + // Example: + // int main() + // { + // ... ... + // ::sofa::pbrpc::RpcServer rpc_server; + // if (!rpc_server.RegisterService(service)) { + // fprintf(stderr, "Register service failed.\n"); + // return EXIT_FAILURE; + // } + // if (!rpc_server.Start(address)) { + // fprintf(stderr, "Start server failed.\n"); + // return EXIT_FAILURE; + // } + // rpc_server.Run(); + // return EXIT_SUCCESS; + // } + // + int Run(); + + // Get the current rpc server options. + RpcServerOptions GetOptions(); + + // Reset the rpc server options. + // + // Current only these options can be reset (others will be ignored): + // * max_pending_buffer_size : will take effective immediately. + // * max_throughput_in : will take effective from the next time slice (0.1s). + // * max_throughput_out : will take effective from the next time slice (0.1s). + // * keep_alive_time: will take effective immediately. + // + // Though you want to reset only part of these options, the other options also + // need to be set. Maybe you can reset by this way: + // RpcServerOptions options = rpc_server->GetOptions(); + // options.max_throughput_in = new_max_throughput_in; // reset some options + // rpc_server->ResetOptions(options); + // + // The old and new value of reset options will be print to INFO log. + void ResetOptions(const RpcServerOptions& options); + + // Register a service. If a service has been registered successfully, and the + // "take_ownership" is true, the service will be taken overby the rpc server + // and will be deleted when the server destroys. + // + // Services are keyed by service full name, so each service can be registered once. + // If the service full name has been registered before, return false. + // + // Preconditions: + // * "service" != NULL + bool RegisterService(google::protobuf::Service* service, bool take_ownership = true); + + // Get the count of current registed services. + int ServiceCount(); + + // Get the count of current alive connections. + int ConnectionCount(); + + // Return true if the server is listening on some address. + bool IsListening(); + +public: + const sofa::pbrpc::shared_ptr& impl() const + { + return _impl; + } + +private: + sofa::pbrpc::shared_ptr _impl; + + SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(RpcServer); +}; // class RpcServer + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_RPC_SERVER_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_server_impl.cc b/src/sofa/pbrpc/rpc_server_impl.cc new file mode 100644 index 0000000..5d35be4 --- /dev/null +++ b/src/sofa/pbrpc/rpc_server_impl.cc @@ -0,0 +1,923 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sofa { +namespace pbrpc { + +RpcServerImpl::RpcServerImpl(const RpcServerOptions& options, + RpcServer::EventHandler* handler) + : _options(options) + , _event_handler(handler) + , _is_running(false) + , _epoch_time(ptime_now()) + , _ticks_per_second(time_duration_seconds(1).ticks()) + , _last_maintain_ticks(0) + , _last_restart_listen_ticks(0) + , _last_switch_stat_slot_ticks(0) + , _last_print_connection_ticks(0) + , _live_stream_count(0) +{ + _service_pool.reset(new ServicePool()); + + _slice_count = std::max(1, 1000 / MAINTAIN_INTERVAL_IN_MS); + _slice_quota_in = _options.max_throughput_in == -1 ? + -1 : std::max(0L, _options.max_throughput_in * 1024L * 1024L) / _slice_count; + _slice_quota_out = _options.max_throughput_out == -1 ? + -1 : std::max(0L, _options.max_throughput_out * 1024L * 1024L) / _slice_count; + _max_pending_buffer_size = + std::max(0L, _options.max_pending_buffer_size * 1024L * 1024L); + _keep_alive_ticks = _options.keep_alive_time == -1 ? + -1 : std::max(1, _options.keep_alive_time) * _ticks_per_second; + _restart_listen_interval_ticks = _ticks_per_second * 3; + _switch_stat_slot_interval_ticks = _ticks_per_second * STAT_SLOT_SECONDS; + _print_connection_interval_ticks = _ticks_per_second * 60; + +#if defined( LOG ) + LOG(INFO) << "RpcServerImpl(): quota_in=" + << (_slice_quota_in == -1 ? -1 : _slice_quota_in * _slice_count / (1024L * 1024L)) + << "MB/s, quota_out=" + << (_slice_quota_out == -1 ? -1 : _slice_quota_out * _slice_count / (1024L * 1024L)) + << "MB/s, max_pending_buffer_size=" + << (_max_pending_buffer_size / (1024L * 1024L)) + << "MB, keep_alive_time=" + << (_keep_alive_ticks == -1 ? -1 : _keep_alive_ticks / _ticks_per_second) + << "seconds"; +#else + SLOG(INFO, "RpcServerImpl(): quota_in=%lldMB/s, quota_out=%lldMB/s" + ", max_pending_buffer_size=%lldMB, keep_alive_time=%lldseconds", + _slice_quota_in == -1 ? -1 : _slice_quota_in * _slice_count / (1024L * 1024L), + _slice_quota_out == -1 ? -1 : _slice_quota_out * _slice_count / (1024L * 1024L), + _max_pending_buffer_size / (1024L * 1024L), + _keep_alive_ticks == -1 ? -1 : _keep_alive_ticks / _ticks_per_second); +#endif +} + +RpcServerImpl::~RpcServerImpl() +{ + SOFA_PBRPC_FUNCTION_TRACE; + Stop(); + _service_pool.reset(); + if (_event_handler) delete _event_handler; +} + +bool RpcServerImpl::Start(const std::string& server_address) +{ + ScopedLocker _(_start_stop_lock); + if (_is_running) return true; + + _flow_controller.reset(new FlowController( + _slice_quota_in == -1, _slice_quota_in, + _slice_quota_out == -1, _slice_quota_out)); + + _maintain_thread_group.reset(new ThreadGroupImpl( + 1, "sofa_pbrpc_server_maintain_thread_group")); + if (!_maintain_thread_group->start()) + { +#if defined( LOG ) + LOG(ERROR) << "Start(): start maintain thread group failed"; +#else + SLOG(ERROR, "Start(): start maintain thread group failed"); +#endif + _maintain_thread_group.reset(); + _flow_controller.reset(); + } + + _work_thread_group.reset(new ThreadGroupImpl( + _options.work_thread_num, "sofa_pbrpc_server_work_thread_group")); + _work_thread_group->set_init_func(_options.work_thread_init_func); + _work_thread_group->set_dest_func(_options.work_thread_dest_func); + if (!_work_thread_group->start()) + { +#if defined( LOG ) + LOG(ERROR) << "Start(): start work thread group failed"; +#else + SLOG(ERROR, "Start(): start work thread group failed"); +#endif + _work_thread_group.reset(); + _maintain_thread_group.reset(); + _flow_controller.reset(); + return false; + } + + _server_address = server_address; + if (!ResolveAddress(_work_thread_group->io_service(), _server_address, &_listen_endpoint)) + { +#if defined( LOG ) + LOG(ERROR) << "Start(): resolve server address failed: " << _server_address; +#else + SLOG(ERROR, "Start(): resolve server address failed: %s", _server_address.c_str()); +#endif + _work_thread_group.reset(); + _maintain_thread_group.reset(); + _flow_controller.reset(); + return false; + } + + _listener.reset(new RpcListener(_work_thread_group->io_service(), _listen_endpoint)); + _listener->set_create_callback(boost::bind( + &RpcServerImpl::OnCreated, shared_from_this(), _1)); + _listener->set_accept_callback(boost::bind( + &RpcServerImpl::OnAccepted, shared_from_this(), _1)); + _listener->set_accept_fail_callback(boost::bind( + &RpcServerImpl::OnAcceptFailed, shared_from_this(), _1, _2)); + if (!_listener->start_listen()) + { +#if defined( LOG ) + LOG(ERROR) << "Start(): listen failed: " << _server_address; +#else + SLOG(ERROR, "Start(): listen failed: %s", _server_address.c_str()); +#endif + _listener.reset(); + _work_thread_group.reset(); + _maintain_thread_group.reset(); + _flow_controller.reset(); + return false; + } +#if defined( LOG ) + LOG(INFO) << "Start(): listen succeed: " << _server_address + << " [" << RpcEndpointToString(_listen_endpoint) << "]"; +#else + SLOG(INFO, "Start(): listen succeed: %s [%s]", + _server_address.c_str(), RpcEndpointToString(_listen_endpoint).c_str()); +#endif + + _timer_worker.reset(new TimerWorker(_maintain_thread_group->io_service())); + _timer_worker->set_time_duration(time_duration_milliseconds(MAINTAIN_INTERVAL_IN_MS)); + _timer_worker->set_work_routine(boost::bind( + &RpcServerImpl::TimerMaintain, shared_from_this(), _1)); + _timer_worker->start(); + + if (!_options.disable_builtin_services) { + _service_pool->RegisterService(new sofa::pbrpc::builtin::BuiltinServiceImpl( + shared_from_this(), _service_pool, _options.disable_list_service)); + } + + _is_running = true; +#if defined( LOG ) + LOG(INFO) << "Start(): rpc server started"; +#else + SLOG(INFO, "Start(): rpc server started"); +#endif + return true; +} + +void RpcServerImpl::Stop() +{ + ScopedLocker _(_start_stop_lock); + if (!_is_running) return; + _is_running = false; + + _timer_worker->stop(); + _listener->close(); + StopStreams(); + _work_thread_group->stop(); + + _timer_worker.reset(); + _listener.reset(); + ClearStreams(); + _maintain_thread_group->stop(); + + _work_thread_group.reset(); + _maintain_thread_group.reset(); + _flow_controller.reset(); + +#if defined( LOG ) + LOG(INFO) << "Stop(): rpc server stopped"; +#else + SLOG(INFO, "Stop(): rpc server stopped"); +#endif +} + +RpcServerOptions RpcServerImpl::GetOptions() +{ + return _options; +} + +void RpcServerImpl::ResetOptions(const RpcServerOptions& options) +{ + int64 old_slice_quota_in = _slice_quota_in; + int64 old_slice_quota_out = _slice_quota_out; + int64 old_max_pending_buffer_size = _max_pending_buffer_size; + int64 old_keep_alive_ticks = _keep_alive_ticks; + + _options.max_throughput_in = options.max_throughput_in; + _options.max_throughput_out = options.max_throughput_out; + _options.max_pending_buffer_size = options.max_pending_buffer_size; + _options.keep_alive_time = options.keep_alive_time; + + _slice_quota_in = _options.max_throughput_in == -1 ? + -1 : std::max(0L, _options.max_throughput_in * 1024L * 1024L) / _slice_count; + _slice_quota_out = _options.max_throughput_out == -1 ? + -1 : std::max(0L, _options.max_throughput_out * 1024L * 1024L) / _slice_count; + _max_pending_buffer_size = + std::max(0L, _options.max_pending_buffer_size * 1024L * 1024L); + _keep_alive_ticks = _options.keep_alive_time == -1 ? + -1 : std::max(1, _options.keep_alive_time) * _ticks_per_second; + + if (_max_pending_buffer_size != old_max_pending_buffer_size) + { + ScopedLocker _(_stream_list_lock); + for (StreamList::iterator it = _stream_list.begin(); it != _stream_list.end(); ++it) + { + (*it)->set_max_pending_buffer_size(_max_pending_buffer_size); + } + } + + if (_slice_quota_in != old_slice_quota_in) + { + _flow_controller->reset_read_quota(_slice_quota_in == -1, _slice_quota_in); + } + + if (_slice_quota_out != old_slice_quota_out) + { + _flow_controller->reset_write_quota(_slice_quota_out == -1, _slice_quota_out); + } + +#if defined( LOG ) + LOG(INFO) << "ResetOptions(): quota_in=" + << (_slice_quota_in == -1 ? -1 : _slice_quota_in * _slice_count / (1024L * 1024L)) + << "MB/s(old " + << (old_slice_quota_in == -1 ? -1 : old_slice_quota_in * _slice_count / (1024L * 1024L)) + << "MB/s), quota_out=" + << (_slice_quota_out == -1 ? -1 : _slice_quota_out * _slice_count / (1024L * 1024L)) + << "MB/s(old " + << (old_slice_quota_out == -1 ? -1 : old_slice_quota_out * _slice_count / (1024L * 1024L)) + << "MB/s), max_pending_buffer_size=" + << (_max_pending_buffer_size / (1024L * 1024L)) + << "MB(old " + << (old_max_pending_buffer_size / (1024L * 1024L)) + << "MB), keep_alive_time=" + << (_keep_alive_ticks == -1 ? -1 : _keep_alive_ticks / _ticks_per_second) + << "seconds(old " + << (old_keep_alive_ticks == -1 ? -1 : old_keep_alive_ticks / _ticks_per_second) + << "seconds)"; +#else + SLOG(INFO, "ResetOptions(): quota_in=%lldMB/s(old %lldMB/s)" + ", quota_out=%lldMB/s(old %lldMB/s)" + ", max_pending_buffer_size=%lldMB(old %lldMB)" + ", keep_alive_time=%lldseconds(old %lldseconds)", + _slice_quota_in == -1 ? -1 : _slice_quota_in * _slice_count / (1024L * 1024L), + old_slice_quota_in == -1 ? -1 : old_slice_quota_in * _slice_count / (1024L * 1024L), + _slice_quota_out == -1 ? -1 : _slice_quota_out * _slice_count / (1024L * 1024L), + old_slice_quota_out == -1 ? -1 : old_slice_quota_out * _slice_count / (1024L * 1024L), + _max_pending_buffer_size / (1024L * 1024L), + old_max_pending_buffer_size / (1024L * 1024L), + _keep_alive_ticks == -1 ? -1 : _keep_alive_ticks / _ticks_per_second, + old_keep_alive_ticks == -1 ? -1 : old_keep_alive_ticks / _ticks_per_second); +#endif +} + +bool RpcServerImpl::RegisterService(google::protobuf::Service* service, bool take_ownership) +{ + return _service_pool->RegisterService(service, take_ownership); +} + +int RpcServerImpl::ServiceCount() +{ + return _service_pool->ServiceCount(); +} + +int RpcServerImpl::ConnectionCount() +{ + ScopedLocker _(_stream_list_lock); + return _stream_list.size(); +} + +void RpcServerImpl::GetPendingStat(int64* pending_message_count, + int64* pending_buffer_size, int64* pending_data_size) +{ + ScopedLocker _(_stream_list_lock); + int64 message_count = 0; + int64 buffer_size = 0; + int64 data_size = 0; + for (StreamList::iterator it = _stream_list.begin(); + it != _stream_list.end(); ++it) + { + message_count += (*it)->pending_message_count(); + buffer_size += (*it)->pending_buffer_size(); + data_size += (*it)->pending_data_size(); + } + *pending_message_count = message_count; + *pending_buffer_size = buffer_size; + *pending_data_size = data_size; +} + +bool RpcServerImpl::IsListening() +{ + ScopedLocker _(_start_stop_lock); + return _is_running && !_listener->is_closed(); +} + +bool RpcServerImpl::RestartListen() +{ + ScopedLocker _(_start_stop_lock); + if (!_is_running) + { +#if defined( LOG ) + LOG(ERROR) << "RestartListen(): server not in running"; +#else + SLOG(ERROR, "RestartListen(): server not in running"); +#endif + return false; + } + + // close listener first + _listener->close(); + + // reset and restart listener + _listener.reset(new RpcListener(_work_thread_group->io_service(), _listen_endpoint)); + _listener->set_create_callback(boost::bind( + &RpcServerImpl::OnCreated, shared_from_this(), _1)); + _listener->set_accept_callback(boost::bind( + &RpcServerImpl::OnAccepted, shared_from_this(), _1)); + _listener->set_accept_fail_callback(boost::bind( + &RpcServerImpl::OnAcceptFailed, shared_from_this(), _1, _2)); + if (!_listener->start_listen()) + { +#if defined( LOG ) + LOG(ERROR) << "RestartListen(): listen failed: " << _server_address; +#else + SLOG(ERROR, "RestartListen(): listen failed: %s", _server_address.c_str()); +#endif + return false; + } + +#if defined( LOG ) + LOG(INFO) << "RestartListen(): restart listener succeed"; +#else + SLOG(INFO, "RestartListen(): restart listener succeed"); +#endif + return true; +} + +void RpcServerImpl::OnCreated(const RpcServerStreamPtr& stream) +{ + stream->set_flow_controller(_flow_controller); + stream->set_received_request_callback( + boost::bind(&RpcServerImpl::OnReceived, + shared_from_this(), _1, _2, _3, _4, _5, _6)); +} + +void RpcServerImpl::OnAccepted(const RpcServerStreamPtr& stream) +{ + if (!_is_running) + { + stream->close("server not running"); + return; + } + + stream->set_max_pending_buffer_size(_max_pending_buffer_size); + stream->reset_ticks((ptime_now() - _epoch_time).ticks()); + + ScopedLocker _(_stream_list_lock); + _stream_list.push_back(stream); +} + +void RpcServerImpl::OnAcceptFailed(RpcErrorCode error_code, const std::string& error_text) +{ + if (!_is_running) + return; + + // callback + if (_event_handler) + { + _event_handler->NotifyAcceptFailed(error_code, error_text); + } +} + +void RpcServerImpl::OnReceived( + const RpcEndpoint& local_endpoint, + const RpcEndpoint& remote_endpoint, + const RpcMeta& meta, + const RpcServerStreamWPtr& stream, + const ReadBufferPtr& buffer, + int64 /* data_size */) +{ + if (!_is_running) + { +#if defined( LOG ) + LOG(ERROR) << "OnReceived(): " << RpcEndpointToString(remote_endpoint) + << ": {" << meta.sequence_id() << "}: server not in running, ignore"; +#else + SLOG(ERROR, "OnReceived(): %s: {%lu}: server not in running, ignore", + RpcEndpointToString(remote_endpoint).c_str(), meta.sequence_id()); +#endif + return; + } + + if (!meta.has_method()) + { +#if defined( LOG ) + LOG(ERROR) << "OnReceived(): " << RpcEndpointToString(remote_endpoint) + << ": {" << meta.sequence_id() << "}: \"method\" field not set in meta"; +#else + SLOG(ERROR, "OnReceived(): %s: {%lu}: \"method\" field not set in meta", + RpcEndpointToString(remote_endpoint).c_str(), meta.sequence_id()); +#endif + SendFailedResponse(stream, meta.sequence_id(), + RPC_ERROR_NOT_SPECIFY_METHOD_NAME, "rpc meta: \"method\" field not set"); + return; + } + + const std::string& method_full_name = meta.method(); + std::string service_name; + std::string method_name; + if (!ParseMethodFullName(method_full_name, &service_name, &method_name)) + { +#if defined( LOG ) + LOG(ERROR) << "OnReceived(): " << RpcEndpointToString(remote_endpoint) + << ": {" << meta.sequence_id() << "}" + << ": invalid method full name: " << method_full_name; +#else + SLOG(ERROR, "OnReceived(): %s: {%lu}: invalid method full name: %s", + RpcEndpointToString(remote_endpoint).c_str(), meta.sequence_id(), + method_full_name.c_str()); +#endif + SendFailedResponse(stream, meta.sequence_id(), + RPC_ERROR_PARSE_METHOD_NAME, "method full name: " + method_full_name); + return; + } + + ServiceBoard* service_board = _service_pool->FindService(service_name); + if (service_board == NULL) + { +#if defined( LOG ) + LOG(ERROR) << "OnReceived(): " << RpcEndpointToString(remote_endpoint) + << ": {" << meta.sequence_id() << "}" + << ": service \"" << service_name << "\" not found" + << ", method full name is \"" << method_full_name << "\""; +#else + SLOG(ERROR, "OnReceived(): %s: {%lu}: " + "service \"%s\" not found, method full name is \"%s\"", + RpcEndpointToString(remote_endpoint).c_str(), meta.sequence_id(), + service_name.c_str(), method_full_name.c_str()); +#endif + SendFailedResponse(stream, meta.sequence_id(), + RPC_ERROR_FOUND_SERVICE, "method full name: " + method_full_name); + return; + } + + google::protobuf::Service* service = service_board->Service(); + const google::protobuf::MethodDescriptor* method = + service->GetDescriptor()->FindMethodByName(method_name); + if (method == NULL) + { +#if defined( LOG ) + LOG(ERROR) << "OnReceived(): " << RpcEndpointToString(remote_endpoint) + << ": {" << meta.sequence_id() << "}" + << ": method \"" << method_name << "\" not found" + << ", method full name is \"" << method_full_name << "\""; +#else + SLOG(ERROR, "OnReceived(): %s: {%lu}: " + "method \"%s\" not found, method full name is \"%s\"", + RpcEndpointToString(remote_endpoint).c_str(), meta.sequence_id(), + method_name.c_str(), method_full_name.c_str()); +#endif + SendFailedResponse(stream, meta.sequence_id(), + RPC_ERROR_FOUND_METHOD, "method full name: " + method_full_name); + return; + } + + google::protobuf::Message* request = service->GetRequestPrototype(method).New(); + SCHECK(request != NULL); + CompressType compress_type = meta.has_compress_type() ? meta.compress_type(): CompressTypeNone; + bool parse_request_return = false; + if (compress_type == CompressTypeNone) + { + parse_request_return = request->ParseFromZeroCopyStream(buffer.get()); + } + else + { + ::sofa::pbrpc::scoped_ptr is( + get_compressed_input_stream(buffer.get(), compress_type)); + parse_request_return = request->ParseFromZeroCopyStream(is.get()); + } + if (!parse_request_return) + { +#if defined( LOG ) + LOG(ERROR) << "OnReceived(): " << RpcEndpointToString(remote_endpoint) + << ": {" << meta.sequence_id() << "}: parse request message failed"; +#else + SLOG(ERROR, "OnReceived(): %s: {%lu}: parse request message failed", + RpcEndpointToString(remote_endpoint).c_str(), meta.sequence_id()); +#endif + SendFailedResponse(stream, meta.sequence_id(), + RPC_ERROR_PARSE_REQUEST_MESSAGE, "method full name: " + method_full_name); + delete request; + return; + } + + google::protobuf::Message* response = service->GetResponsePrototype(method).New(); + SCHECK(response != NULL); + + RpcController* controller = new RpcController(); + SCHECK(controller != NULL); + const RpcControllerImplPtr& cntl = controller->impl(); + cntl->SetSequenceId(meta.sequence_id()); + cntl->SetMethodId(method_full_name); + cntl->SetLocalEndpoint(local_endpoint); + cntl->SetRemoteEndpoint(remote_endpoint); + cntl->SetRpcServerStream(stream); + cntl->SetRequestReceivedTime(ptime_now()); + cntl->SetResponseCompressType(meta.has_expected_response_compress_type() ? + meta.expected_response_compress_type() : CompressTypeNone); + + MethodBoard* method_board = service_board->Method(method->index()); + method_board->ReportProcessBegin(); + + google::protobuf::Closure* done = NewClosure( + &RpcServerImpl::OnCallMethodDone, controller, request, response, + method_board, ptime_now()); + service->CallMethod(method, controller, request, response, done); +} + +void RpcServerImpl::OnCallMethodDone( + RpcController* controller, + google::protobuf::Message* request, + google::protobuf::Message* response, + MethodBoard* method_board, + PTime start_time) +{ + int64 process_time_us = (ptime_now() - start_time).total_microseconds(); + const RpcControllerImplPtr& cntl = controller->impl(); + if (cntl->Failed()) + { +#if defined( LOG ) + LOG(ERROR) << "OnCallMethodDone(): call method \"" << cntl->MethodId() + << "\" failed: " << RpcErrorCodeToString(cntl->ErrorCode()) + << ": " << cntl->Reason(); +#else + SLOG(ERROR, "OnCallMethodDone(): call method \"%s\" failed: %s: %s", + cntl->MethodId().c_str(), + RpcErrorCodeToString(cntl->ErrorCode()), + cntl->Reason().c_str()); +#endif + method_board->ReportProcessEnd(false, process_time_us); + SendFailedResponse(cntl->RpcServerStream(), cntl->SequenceId(), + cntl->ErrorCode(), cntl->Reason()); + } + else + { +#if defined( LOG ) +#else + SLOG(DEBUG, "OnCallMethodDone(): call method \"%s\" succeed", + cntl->MethodId().c_str()); +#endif + method_board->ReportProcessEnd(true, process_time_us); + SendSucceedResponse(cntl->RpcServerStream(), cntl->SequenceId(), + cntl->ResponseCompressType(), response); + } + + delete request; + delete response; + delete controller; +} + +void RpcServerImpl::SendFailedResponse( + const RpcServerStreamWPtr& stream, + uint64 sequence_id, + int32 error_code, + const std::string& reason) +{ + RpcServerStreamPtr real_stream = stream.lock(); + if (!real_stream) + { +#if defined( LOG ) + LOG(ERROR) << "SendFailedResponse(): {" << sequence_id << "}: stream already closed"; +#else + SLOG(ERROR, "SendFailedResponse(): {%lu}: stream already closed", sequence_id); +#endif + return; + } + + RpcMeta meta; + meta.set_type(RpcMeta::RESPONSE); + meta.set_sequence_id(sequence_id); + meta.set_failed(true); + meta.set_error_code(error_code); + meta.set_reason(reason); + + RpcMessageHeader header; + int header_size = static_cast(sizeof(header)); + WriteBuffer write_buffer; + int64 header_pos = write_buffer.Reserve(header_size); + if (header_pos < 0) + { +#if defined( LOG ) + LOG(ERROR) << "SendFailedResponse(): {" << sequence_id << "}" + << ": reserve rpc message header failed"; +#else + SLOG(ERROR, "SendFailedResponse(): {%lu}: reserve rpc message header failed", sequence_id); +#endif + return; + } + if (!meta.SerializeToZeroCopyStream(&write_buffer)) + { +#if defined( LOG ) + LOG(ERROR) << "SendFailedResponse(): {" << sequence_id << "}" + << ": serialize rpc meta failed"; +#else + SLOG(ERROR, "SendFailedResponse(): {%lu}: serialize rpc meta failed", sequence_id); +#endif + return; + } + header.meta_size = static_cast(write_buffer.ByteCount() - header_pos - header_size); + header.data_size = 0; + header.message_size = header.meta_size + header.data_size; + write_buffer.SetData(header_pos, reinterpret_cast(&header), header_size); + + ReadBufferPtr read_buffer(new ReadBuffer()); + write_buffer.SwapOut(read_buffer.get()); + + real_stream->send_response(read_buffer, + boost::bind(&RpcServerImpl::OnSendResponseDone, + real_stream->remote_endpoint(), sequence_id, _1)); +} + +void RpcServerImpl::SendSucceedResponse( + const RpcServerStreamWPtr& stream, + uint64 sequence_id, + CompressType compress_type, + google::protobuf::Message* response) +{ + RpcServerStreamPtr real_stream = stream.lock(); + if (!real_stream) + { +#if defined( LOG ) + LOG(ERROR) << "SendSucceedResponse(): {" << sequence_id << "}" + << ": stream already closed"; +#else + SLOG(ERROR, "SendSucceedResponse(): {%lu}: stream already closed", sequence_id); +#endif + return; + } + + RpcMeta meta; + meta.set_type(RpcMeta::RESPONSE); + meta.set_sequence_id(sequence_id); + meta.set_failed(false); + meta.set_compress_type(compress_type); + + RpcMessageHeader header; + int header_size = static_cast(sizeof(header)); + WriteBuffer write_buffer; + int64 header_pos = write_buffer.Reserve(header_size); + if (header_pos < 0) + { +#if defined( LOG ) + LOG(ERROR) << "SendSucceedResponse(): {" << sequence_id << "}" + << ": reserve rpc message header failed"; +#else + SLOG(ERROR, "SendSucceedResponse(): {%lu}: reserve rpc message header failed", sequence_id); +#endif + return; + } + if (!meta.SerializeToZeroCopyStream(&write_buffer)) + { +#if defined( LOG ) + LOG(ERROR) << "SendSucceedResponse(): {" << sequence_id << "}" + << ": serialize rpc meta failed"; +#else + SLOG(ERROR, "SendSucceedResponse(): {%lu}: serialize rpc meta failed", sequence_id); +#endif + SendFailedResponse(stream, sequence_id, + RPC_ERROR_SERIALIZE_RESPONSE, "serialize rpc meta failed"); + return; + } + header.meta_size = static_cast(write_buffer.ByteCount() - header_pos - header_size); + bool serialize_response_return = false; + if (compress_type == CompressTypeNone) + { + serialize_response_return = response->SerializeToZeroCopyStream(&write_buffer); + } + else + { + ::sofa::pbrpc::scoped_ptr os( + get_compressed_output_stream(&write_buffer, compress_type)); + serialize_response_return = response->SerializeToZeroCopyStream(os.get()); + os->Flush(); + } + if (!serialize_response_return) + { +#if defined( LOG ) + LOG(ERROR) << "SendSucceedResponse(): {" << sequence_id << "}" + << ": serialize response message failed"; +#else + SLOG(ERROR, "SendSucceedResponse(): {%lu}: serialize response message failed", sequence_id); +#endif + SendFailedResponse(stream, sequence_id, + RPC_ERROR_SERIALIZE_RESPONSE, "serialize response message failed"); + return; + } + header.data_size = write_buffer.ByteCount() - header_pos - header_size - header.meta_size; + header.message_size = header.meta_size + header.data_size; + write_buffer.SetData(header_pos, reinterpret_cast(&header), header_size); + + ReadBufferPtr read_buffer(new ReadBuffer()); + write_buffer.SwapOut(read_buffer.get()); + + real_stream->send_response(read_buffer, + boost::bind(&RpcServerImpl::OnSendResponseDone, + real_stream->remote_endpoint(), sequence_id, _1)); +} + +void RpcServerImpl::OnSendResponseDone( + const RpcEndpoint& remote_endpoint, + uint64 sequence_id, + RpcErrorCode error_code) +{ + if (error_code == RPC_SUCCESS) + { +#if defined( LOG ) +#else + SLOG(DEBUG, "OnSendResponseDone(): %s {%lu}: send succeed", + RpcEndpointToString(remote_endpoint).c_str(), sequence_id); +#endif + } + else + { +#if defined( LOG ) + LOG(ERROR) << "OnSendResponseDone(): " << RpcEndpointToString(remote_endpoint) + << " {" << sequence_id << "}" + << ": send failed: " << RpcErrorCodeToString(error_code); +#else + SLOG(ERROR, "OnSendResponseDone(): %s {%lu}: send failed: %s", + RpcEndpointToString(remote_endpoint).c_str(), sequence_id, + RpcErrorCodeToString(error_code)); +#endif + } +} + +void RpcServerImpl::StopStreams() +{ + ScopedLocker _(_stream_list_lock); + for (StreamList::iterator it = _stream_list.begin(); + it != _stream_list.end(); ++it) + { + (*it)->close("server stopped"); + } +} + +void RpcServerImpl::ClearStreams() +{ + ScopedLocker _(_stream_list_lock); + _stream_list.clear(); +} + +void RpcServerImpl::TimerMaintain(const PTime& now) +{ + SOFA_PBRPC_FUNCTION_TRACE; + + int64 now_ticks = (now - _epoch_time).ticks(); + + // check listener, if closed, then try to restart it every interval. + if (_listener->is_closed() + && now_ticks - _last_restart_listen_ticks >= _restart_listen_interval_ticks) + { + _last_restart_listen_ticks = now_ticks; + RestartListen(); + } + + // check streams, if closed, then remove from list + std::list live_streams; + std::list closed_streams; + int live_count = 0; + { + ScopedLocker _(_stream_list_lock); + for (StreamList::iterator it = _stream_list.begin(); + it != _stream_list.end(); ) + { + const RpcServerStreamPtr& stream = *it; + + if (_keep_alive_ticks != -1 + && now_ticks - stream->last_rw_ticks() >= _keep_alive_ticks) + { + stream->close("keep alive timeout"); + } + + if (stream->is_closed()) + { + closed_streams.push_back(stream); + it = _stream_list.erase(it); + } + else + { + stream->reset_ticks(now_ticks); + live_streams.push_back(stream); + ++live_count; + ++it; + } + } + } + _live_stream_count = live_count; + + // flow control + if (_slice_quota_in != -1) + { + // reset quota pool + _flow_controller->reset_read_quota(_slice_quota_in); + + // collect streams need to trigger + std::vector trigger_list; + for (std::list::iterator it = live_streams.begin(); + it != live_streams.end(); ++it) + { + int token = (*it)->read_quota_token(); + if (token <= 0) + { + // only need trigger streams whose token <= 0 + trigger_list.push_back(FlowControlItem(token, (*it).get())); + } + } + + // sort by token: token closer to zero, earlier to trigger + std::sort(trigger_list.begin(), trigger_list.end()); + + // trigger in order + for (std::vector::iterator t_it = trigger_list.begin(); + t_it != trigger_list.end(); ++t_it) + { + t_it->stream->trigger_receive(); + } + } + if (_slice_quota_out != -1) + { + // reset quota pool + _flow_controller->reset_write_quota(_slice_quota_out); + + // collect streams need to trigger + std::vector trigger_list; + for (std::list::iterator it = live_streams.begin(); + it != live_streams.end(); ++it) + { + int token = (*it)->write_quota_token(); + if (token <= 0) + { + // only need trigger streams whose token <= 0 + trigger_list.push_back(FlowControlItem(token, (*it).get())); + } + } + + // sort by token: token closer to zero, earlier to trigger + std::sort(trigger_list.begin(), trigger_list.end()); + + // trigger in order + for (std::vector::iterator t_it = trigger_list.begin(); + t_it != trigger_list.end(); ++t_it) + { + t_it->stream->trigger_send(); + } + } + + if (now_ticks - _last_switch_stat_slot_ticks >= _switch_stat_slot_interval_ticks) + { + _last_switch_stat_slot_ticks = now_ticks; + _service_pool->NextSlot(); + } + + if (now_ticks - _last_print_connection_ticks >= _print_connection_interval_ticks) + { + _last_print_connection_ticks = now_ticks; +#if defined( LOG ) + LOG(INFO) << "TimerMaintain(): countof(RpcListener)=" + << SOFA_PBRPC_GET_RESOURCE_COUNTER(RpcListener) + << ", countof(RpcByteStream)=" << SOFA_PBRPC_GET_RESOURCE_COUNTER(RpcByteStream) + << ", live_stream_count=" << _live_stream_count; +#else + SLOG(INFO, "TimerMaintain(): countof(RpcListener)=%ld" + ", countof(RpcByteStream)=%ld, live_stream_count=%d", + SOFA_PBRPC_GET_RESOURCE_COUNTER(RpcListener), + SOFA_PBRPC_GET_RESOURCE_COUNTER(RpcByteStream), + _live_stream_count); +#endif + } + + _last_maintain_ticks = now_ticks; +} + +bool RpcServerImpl::ParseMethodFullName(const std::string& method_full_name, + std::string* service_full_name, std::string* method_name) +{ + std::string::size_type pos = method_full_name.rfind('.'); + if (pos == std::string::npos) return false; + *service_full_name = method_full_name.substr(0, pos); + *method_name = method_full_name.substr(pos + 1); + return true; +} + +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_server_impl.h b/src/sofa/pbrpc/rpc_server_impl.h new file mode 100644 index 0000000..4c0efc3 --- /dev/null +++ b/src/sofa/pbrpc/rpc_server_impl.h @@ -0,0 +1,171 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_RPC_SERVER_IMPL_H_ +#define _SOFA_PBRPC_RPC_SERVER_IMPL_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sofa { +namespace pbrpc { + +class RpcServerImpl : public sofa::pbrpc::enable_shared_from_this +{ +public: + static const int MAINTAIN_INTERVAL_IN_MS = 100; + +public: + RpcServerImpl(const RpcServerOptions& options, + RpcServer::EventHandler* handler); + + virtual ~RpcServerImpl(); + + bool Start(const std::string& server_address); + + void Stop(); + + RpcServerOptions GetOptions(); + + void ResetOptions(const RpcServerOptions& options); + + bool RegisterService(google::protobuf::Service* service, bool take_ownership); + + int ServiceCount(); + + int ConnectionCount(); + + void GetPendingStat(int64* pending_message_count, + int64* pending_buffer_size, int64* pending_data_size); + + bool IsListening(); + + // Restart the listener. It will restart listening anyway, even if it is already in + // listening. Return false if the server is not started, or fail to restart listening. + bool RestartListen(); + +private: + void OnCreated(const RpcServerStreamPtr& stream); + + void OnAccepted(const RpcServerStreamPtr& stream); + + void OnAcceptFailed( + RpcErrorCode error_code, + const std::string& error_text); + + void OnReceived( + const RpcEndpoint& local_endpoint, + const RpcEndpoint& remote_endpoint, + const RpcMeta& meta, + const RpcServerStreamWPtr& stream, + const ReadBufferPtr& buffer, + int64 data_size); + + static void OnCallMethodDone( + RpcController* controller, + google::protobuf::Message* request, + google::protobuf::Message* response, + MethodBoard* method_board, + PTime start_time); + + static void SendFailedResponse( + const RpcServerStreamWPtr& stream, + uint64 sequence_id, + int32 error_code, + const std::string& reason); + + static void SendSucceedResponse( + const RpcServerStreamWPtr& stream, + uint64 sequence_id, + CompressType compress_type, + google::protobuf::Message* response); + + static void OnSendResponseDone( + const RpcEndpoint& remote_endpoint, + uint64 sequence_id, + RpcErrorCode error_code); + + void StopStreams(); + + void ClearStreams(); + + void TimerMaintain(const PTime& now); + + static bool ParseMethodFullName(const std::string& method_full_name, + std::string* service_full_name, std::string* method_name); + +private: + struct FlowControlItem + { + int token; // always <= 0 + RpcServerStream* stream; + + FlowControlItem(int t, RpcServerStream* s) : token(t), stream(s) {} + // comparator: nearer to zero, higher priority + bool operator< (const FlowControlItem& o) const + { + return token > o.token; + } + }; + +private: + RpcServerOptions _options; + RpcServer::EventHandler* _event_handler; + volatile bool _is_running; + MutexLock _start_stop_lock; + + PTime _epoch_time; + int64 _ticks_per_second; + int64 _last_maintain_ticks; + int64 _last_restart_listen_ticks; + int64 _last_switch_stat_slot_ticks; + int64 _last_print_connection_ticks; + + int64 _slice_count; + int64 _slice_quota_in; + int64 _slice_quota_out; + int64 _max_pending_buffer_size; + int64 _keep_alive_ticks; + int64 _restart_listen_interval_ticks; + int64 _switch_stat_slot_interval_ticks; + int64 _print_connection_interval_ticks; + + ServicePoolPtr _service_pool; + + FlowControllerPtr _flow_controller; + + ThreadGroupImplPtr _maintain_thread_group; + ThreadGroupImplPtr _work_thread_group; + + std::string _server_address; + RpcEndpoint _listen_endpoint; + RpcListenerPtr _listener; + + TimerWorkerPtr _timer_worker; + + typedef std::deque StreamList; + StreamList _stream_list; + FastLock _stream_list_lock; + volatile int _live_stream_count; + + SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(RpcServerImpl); +}; // class RpcServerImpl + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_RPC_SERVER_IMPL_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_server_stream.h b/src/sofa/pbrpc/rpc_server_stream.h new file mode 100644 index 0000000..b013038 --- /dev/null +++ b/src/sofa/pbrpc/rpc_server_stream.h @@ -0,0 +1,167 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_RPC_SERVER_STREAM_H_ +#define _SOFA_PBRPC_RPC_SERVER_STREAM_H_ + +#include +#include +#include +#include + +namespace sofa { +namespace pbrpc { + +// Callback function when received request message. +typedef boost::function ReceivedRequestCallback; + +/// Callback function when send response message done. +// * if "status" == RPC_SUCCESS, means send response succeed; +// * else, means send failed. +typedef boost::function SendResponseCallback; + +class RpcServerStream : public RpcMessageStream +{ +public: + RpcServerStream(IOService& io_service) + : RpcMessageStream(ROLE_TYPE_SERVER, io_service, RpcEndpoint()) + {} + + virtual ~RpcServerStream() + { + SOFA_PBRPC_FUNCTION_TRACE; + close("stream destructed"); + } + + // Set the callback function when received request. + void set_received_request_callback( + const ReceivedRequestCallback& callback) + { + _received_request_callback = callback; + } + + // Get the callback function when received request. + const ReceivedRequestCallback& received_request_callback() const + { + return _received_request_callback; + } + + // Send response message. No timeout is set for sending response. + // If send done, on mater succeed or failed, SendResponseCallback will be called. + // @param message the response message to send, including the header. not null. + // @param callback the callback function when send succeed or failed. NULL means no callback. + void send_response(const ReadBufferPtr& message, + const SendResponseCallback& callback) + { + SOFA_PBRPC_FUNCTION_TRACE; + + async_send_message(message, callback); + } + +private: + virtual void on_closed() + { + SOFA_PBRPC_FUNCTION_TRACE; + + // do nothing + } + + virtual bool on_sending( + const ReadBufferPtr& /* response_message */, + const SendResponseCallback& /* callback */) + { + SOFA_PBRPC_FUNCTION_TRACE; + + return true; + } + + virtual void on_sent( + const ReadBufferPtr& /* response_message */, + const SendResponseCallback& callback) + { + SOFA_PBRPC_FUNCTION_TRACE; + + if (callback) callback(RPC_SUCCESS); + } + + virtual void on_send_failed( + RpcErrorCode error_code, + const ReadBufferPtr& /* response_message */, + const SendResponseCallback& callback) + { + SOFA_PBRPC_FUNCTION_TRACE; + + if (callback) callback(error_code); + } + + virtual void on_received( + const ReadBufferPtr& message, + int meta_size, + int64 data_size) + { + SOFA_PBRPC_FUNCTION_TRACE; + + RpcMeta meta; + if (!meta.ParseFromBoundedZeroCopyStream(message.get(), meta_size)) + { +#if defined( LOG ) + LOG(ERROR) << "on_received(): " << RpcEndpointToString(_remote_endpoint) + << ": parse rpc meta failed"; +#else + SLOG(ERROR, "on_received(): %s: parse rpc meta failed", + RpcEndpointToString(_remote_endpoint).c_str()); +#endif + return; + } + + if (meta.type() == RpcMeta::REQUEST) + { + if (_received_request_callback) + { + _received_request_callback( + _local_endpoint, + _remote_endpoint, + meta, + RpcServerStreamWPtr( + sofa::pbrpc::dynamic_pointer_cast(shared_from_this())), + message, + data_size); + } + } + else + { + // TODO handle un-expected message type + // + // just ignore it +#if defined( LOG ) + LOG(ERROR) << "on_received(): " << RpcEndpointToString(_remote_endpoint) + << " {" << meta.sequence_id() << "}:" + << " un-expected message type: " << meta.type(); +#else + SLOG(ERROR, "on_received(): %s {%lu}: un-expected message type: %d", + RpcEndpointToString(_remote_endpoint).c_str(), + meta.sequence_id(), meta.type()); +#endif + return; + } + } + +private: + ReceivedRequestCallback _received_request_callback; +}; // class RpcServerStream + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_RPC_SERVER_STREAM_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rpc_timeout_manager.h b/src/sofa/pbrpc/rpc_timeout_manager.h new file mode 100644 index 0000000..f80b877 --- /dev/null +++ b/src/sofa/pbrpc/rpc_timeout_manager.h @@ -0,0 +1,282 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_RPC_TIMEOUT_MANAGER_H_ +#define _SOFA_PBRPC_RPC_TIMEOUT_MANAGER_H_ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +namespace sofa { +namespace pbrpc { + +class RpcTimeoutManager : public sofa::pbrpc::enable_shared_from_this +{ +public: + RpcTimeoutManager(IOService& io_service) + : _io_service(io_service) + , _is_running(false) + , _epoch_time(ptime_now()) + , _next_id(1u) + {} + + ~RpcTimeoutManager() + { + SOFA_PBRPC_FUNCTION_TRACE; + stop(); + } + + bool is_running() const + { + return _is_running; + } + + void start() + { + ScopedLocker _(_start_stop_lock); + if (_is_running) + return; + _is_running = true; + + _timer_worker.reset(new TimerWorker(_io_service)); + _timer_worker->set_time_duration(time_duration_milliseconds(100)); + _timer_worker->set_work_routine(boost::bind( + &RpcTimeoutManager::timer_run, shared_from_this(), _1)); + _timer_worker->start(); + } + + void stop() + { + ScopedLocker _(_start_stop_lock); + if (!_is_running) + return; + _is_running = false; + + _timer_worker->stop(); + + clear(); + _timer_worker.reset(); + } + + // Add a timeout event. + // If "expiration" of the "cntl" is a special value or already timeout, return false. + // Else put the "cntl" into the manager, and return true. + bool add(const RpcControllerImplPtr& cntl) + { + const PTime& expiration = cntl->Expiration(); + if (expiration.is_special() || expiration <= _epoch_time) + { + cntl->SetTimeoutId(0u); + return false; + } + int64 expiration_ticks = (expiration - _epoch_time).ticks(); + { + ScopedLocker _(_add_list_lock); + uint64 timeout_id = _next_id++; + cntl->SetTimeoutId(timeout_id); + _add_list.push_back(Event(timeout_id, expiration_ticks, cntl)); + } + return true; + } + + // Erase a given timeout event. + void erase(uint64 id) + { + if (id == 0u) return; + ScopedLocker _(_erase_set_lock); + _erase_set.insert(id); + } + +private: + void clear() + { + { + ScopedLocker _(_add_list_lock); + _add_list.clear(); + } + { + ScopedLocker _(_erase_set_lock); + _erase_set.clear(); + } + { + ScopedLocker _(_events_lock); + _events.clear(); + } + } + + void timer_run(const PTime& now) + { + if (!_is_running) return; + int64 now_ticks = (now - _epoch_time).ticks(); + + // process add list and erase list + EventList tmp_add_list; + { + ScopedLocker _(_add_list_lock); + tmp_add_list.swap(_add_list); + } + IdSet tmp_erase_set; + { + ScopedLocker _(_erase_set_lock); + tmp_erase_set.swap(_erase_set); + } + + ScopedLocker _(_events_lock); + EventList::iterator add_it = tmp_add_list.begin(); + IdSet::iterator erase_it = tmp_erase_set.begin(); + while (add_it != tmp_add_list.end() && erase_it != tmp_erase_set.end()) + { + if (add_it->id < *erase_it) + { + if (add_it->expiration <= now_ticks) + { + // expired, notify + notify_timeout(add_it->cntl); + } + else + { + // add into EventSet + _events.insert(*add_it); + } + ++add_it; + } + else if (add_it->id > *erase_it) + { + // erase from EventSet + _events.get().erase(*erase_it); + ++erase_it; + } + else // add_it->id == *erase_it + { + // ignore it + ++add_it; + ++erase_it; + } + } + while (add_it != tmp_add_list.end()) + { + if (add_it->expiration <= now_ticks) + { + // expired, notify + notify_timeout(add_it->cntl); + } + else + { + // add into EventSet + _events.insert(*add_it); // add into EventSet + } + ++add_it; + } + while (erase_it != tmp_erase_set.end()) + { + // erase from EventSet + _events.get().erase(*erase_it); + ++erase_it; + } + + // process EventSet + ExpirationIndex& exp_index = _events.get(); + ExpirationIndex::iterator exp_end = exp_index.upper_bound(now_ticks); + for (ExpirationIndex::iterator exp_it = exp_index.begin(); + exp_it != exp_end; ++exp_it) + { + // expired, notify + notify_timeout(exp_it->cntl); + } + exp_index.erase(exp_index.begin(), exp_end); + } + +private: + void notify_timeout(const RpcControllerImplWPtr& weak_cntl) + { + RpcControllerImplPtr cntl = weak_cntl.lock(); + if (cntl) { + cntl->SetTimeoutId(0u); + cntl->Done(RPC_ERROR_REQUEST_TIMEOUT, "timeout"); + } + } + +private: + struct Event + { + uint64 id; // 0 means invalid id + int64 expiration; + RpcControllerImplWPtr cntl; + Event(uint64 i, int64 e, const RpcControllerImplWPtr& c) + : id(i), expiration(e), cntl(c) {} + Event(const Event& o) + : id(o.id), expiration(o.expiration), cntl(o.cntl) {} + Event& operator=(const Event& o) { + if (this != &o) { + id = o.id; + expiration = o.expiration; + cntl = o.cntl; + } + return *this; + } + void swap(Event& o) { + std::swap(id, o.id); + std::swap(expiration, o.expiration); + cntl.swap(o.cntl); + } + }; + + typedef boost::multi_index_container< + Event, + boost::multi_index::indexed_by< + boost::multi_index::ordered_unique< boost::multi_index::member< + Event, uint64, &Event::id + > >, + boost::multi_index::ordered_non_unique< boost::multi_index::member< + Event, int64, &Event::expiration + > > + > + > EventSet; + + enum { + INDEX_BY_ID = 0, + INDEX_BY_EXPIRATION = 1, + }; + + typedef EventSet::nth_index::type ExpirationIndex; + typedef EventSet::nth_index::type IdIndex; + typedef std::deque EventList; + typedef std::set IdSet; + + IOService& _io_service; + volatile bool _is_running; + MutexLock _start_stop_lock; + PTime _epoch_time; + + uint64 _next_id; + EventSet _events; + FastLock _events_lock; + + EventList _add_list; // must be in order of id + FastLock _add_list_lock; + IdSet _erase_set; // in order of id + FastLock _erase_set_lock; + + TimerWorkerPtr _timer_worker; + + SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(RpcTimeoutManager); +}; // class RpcTimeoutManager + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_RPC_TIMEOUT_MANAGER_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/rw_lock.h b/src/sofa/pbrpc/rw_lock.h new file mode 100644 index 0000000..d5b8821 --- /dev/null +++ b/src/sofa/pbrpc/rw_lock.h @@ -0,0 +1,76 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_RW_LOCK_H_ +#define _SOFA_PBRPC_RW_LOCK_H_ + +#include + +namespace sofa { +namespace pbrpc { + +class RWLock +{ +public: + RWLock() + { + pthread_rwlock_init(&_lock, NULL); + } + ~RWLock() + { + pthread_rwlock_destroy(&_lock); + } + void lock() + { + pthread_rwlock_wrlock(&_lock); + } + void lock_shared() + { + pthread_rwlock_rdlock(&_lock); + } + void unlock() + { + pthread_rwlock_unlock(&_lock); + } +private: + pthread_rwlock_t _lock; +}; + +class ReadLocker +{ +public: + explicit ReadLocker(RWLock* lock) : _lock(lock) + { + _lock->lock_shared(); + } + ~ReadLocker() + { + _lock->unlock(); + } +private: + RWLock* _lock; +}; +class WriteLocker +{ +public: + explicit WriteLocker(RWLock* lock) : _lock(lock) + { + _lock->lock(); + } + ~WriteLocker() + { + _lock->unlock(); + } +private: + RWLock* _lock; +}; + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_RW_LOCK_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/scoped_locker.h b/src/sofa/pbrpc/scoped_locker.h new file mode 100644 index 0000000..144a28e --- /dev/null +++ b/src/sofa/pbrpc/scoped_locker.h @@ -0,0 +1,43 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_SCOPED_LOCKER_H_ +#define _SOFA_PBRPC_SCOPED_LOCKER_H_ + +namespace sofa { +namespace pbrpc { + +template +class ScopedLocker +{ +public: + explicit ScopedLocker(LockType& lock) + : _lock(&lock) + { + _lock->lock(); + } + + explicit ScopedLocker(LockType* lock) + : _lock(lock) + { + _lock->lock(); + } + + ~ScopedLocker() + { + _lock->unlock(); + } + +private: + LockType* _lock; +}; // class ScopedLocker + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_SCOPED_LOCKER_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/service_pool.h b/src/sofa/pbrpc/service_pool.h new file mode 100644 index 0000000..d2a00d0 --- /dev/null +++ b/src/sofa/pbrpc/service_pool.h @@ -0,0 +1,404 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_SERVICE_POOL_H_ +#define _SOFA_PBRPC_SERVICE_POOL_H_ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +namespace sofa { +namespace pbrpc { + +#define SERVICE_CACHE_SLOT_COUNT 1019 +#define STAT_SLOT_COUNT 602 +#define STAT_SLOT_SECONDS 1 + +// All the time is in micro-seconds. +struct StatSlot +{ + int64 succeed_count; + int64 succeed_process_time; + int64 succeed_max_process_time; + int64 failed_count; + int64 failed_process_time; + int64 failed_max_process_time; +}; + +class MethodBoard +{ +public: + MethodBoard() : _desc(NULL), _slot_index(0) + { + memset(_stat_slots, 0, sizeof(_stat_slots)); + } + + ~MethodBoard() {} + + void SetDescriptor(const google::protobuf::MethodDescriptor* desc) + { + _desc = desc; + } + + const google::protobuf::MethodDescriptor* Descriptor() + { + return _desc; + } + + void ReportProcessBegin() + { + } + + void ReportProcessEnd(bool succeed, int64 time_in_us) + { + volatile StatSlot* slot = &_stat_slots[_slot_index]; + if (succeed) { + ++slot->succeed_count; + slot->succeed_process_time += time_in_us; + if (slot->succeed_max_process_time < time_in_us) { + slot->succeed_max_process_time = time_in_us; + } + } + else { + ++slot->failed_count; + slot->failed_process_time += time_in_us; + if (slot->failed_max_process_time < time_in_us) { + slot->failed_max_process_time = time_in_us; + } + } + } + + void NextSlot() + { + _slot_index = ((_slot_index + 1 == STAT_SLOT_COUNT) ? 0 : _slot_index + 1); + memset(&_stat_slots[_slot_index], 0, sizeof(StatSlot)); + } + + void LatestStats(int slot_count, StatSlot* stat_out) + { + SCHECK(slot_count > 0 && slot_count <= STAT_SLOT_COUNT); + SCHECK(stat_out != NULL); + memset(stat_out, 0, sizeof(StatSlot)); + int index = (_slot_index == 0 ? STAT_SLOT_COUNT - 1 : _slot_index - 1); + while (slot_count > 0) { + volatile StatSlot* slot = &_stat_slots[index]; + stat_out->succeed_count += slot->succeed_count; + stat_out->succeed_process_time += slot->succeed_process_time; + if (stat_out->succeed_max_process_time < slot->succeed_max_process_time) { + stat_out->succeed_max_process_time = slot->succeed_max_process_time; + } + stat_out->failed_count += slot->failed_count; + stat_out->failed_process_time += slot->failed_process_time; + if (stat_out->failed_max_process_time < slot->failed_max_process_time) { + stat_out->failed_max_process_time = slot->failed_max_process_time; + } + --slot_count; + index = (index == 0 ? STAT_SLOT_COUNT - 1 : index - 1); + } + } + + void LatestStats(int slot_count, sofa::pbrpc::builtin::MethodStat* stat_out) + { + SCHECK(stat_out != NULL); + stat_out->Clear(); + StatSlot stat; + LatestStats(slot_count, &stat); + stat_out->set_method_name(_desc->full_name()); + stat_out->set_succeed_count(stat.succeed_count); + stat_out->set_succeed_avg_time_us(stat.succeed_count > 0 ? + (float)stat.succeed_process_time / stat.succeed_count : 0); + stat_out->set_succeed_max_time_us(stat.succeed_max_process_time); + stat_out->set_failed_count(stat.failed_count); + stat_out->set_failed_avg_time_us(stat.failed_count > 0 ? + (float)stat.failed_process_time / stat.failed_count : 0); + stat_out->set_failed_max_time_us(stat.failed_max_process_time); + } + +private: + const google::protobuf::MethodDescriptor* _desc; + StatSlot _stat_slots[STAT_SLOT_COUNT]; + volatile int _slot_index; +}; + +class ServiceBoard +{ +public: + ServiceBoard(ServiceBoard* next, google::protobuf::Service* svc, bool own) + : _next(next), _svc(svc), _own(own) + { + _svc_desc = _svc->GetDescriptor(); + _method_count = _svc_desc->method_count(); + _method_boards = new MethodBoard[_method_count]; + for (int i = 0; i < _method_count; ++i) { + _method_boards[i].SetDescriptor(_svc_desc->method(i)); + } + } + + ~ServiceBoard() + { + delete[] _method_boards; + if (_own) { + delete _svc; + } + } + + ServiceBoard* Next() + { + return _next; + } + + const std::string& ServiceName() + { + return _svc_desc->full_name(); + } + + google::protobuf::Service* Service() + { + return _svc; + } + + MethodBoard* Method(int method_id) + { + SCHECK(method_id >=0 && method_id < _method_count); + return &_method_boards[method_id]; + } + + void ReportProcessBegin(int method_id) + { + SCHECK(method_id >=0 && method_id < _method_count); + _method_boards[method_id].ReportProcessBegin(); + } + + void ReportProcessEnd(int method_id, bool succeed, int64 time_in_us) + { + SCHECK(method_id >=0 && method_id < _method_count); + _method_boards[method_id].ReportProcessEnd(succeed, time_in_us); + } + + void NextSlot() + { + for (int i = 0; i < _method_count; ++i) { + _method_boards[i].NextSlot(); + } + } + + void LatestStats(int method_id, int slot_count, StatSlot* stat_out) + { + SCHECK(method_id >=0 && method_id < _method_count); + _method_boards[method_id].LatestStats(slot_count, stat_out); + } + + void LatestStats(int method_id, int slot_count, sofa::pbrpc::builtin::MethodStat* stat_out) + { + SCHECK(method_id >=0 && method_id < _method_count); + _method_boards[method_id].LatestStats(slot_count, stat_out); + } + + void LatestStats(int64 expect_period, sofa::pbrpc::builtin::ServiceStat* stat_out) + { + SCHECK(stat_out != NULL); + stat_out->Clear(); + int64 real_period; + int slot_count; + GetRealPeriod(expect_period, &real_period, &slot_count); + stat_out->set_service_name(ServiceName()); + stat_out->set_period_seconds(real_period); + stat_out->set_succeed_count(0); + stat_out->set_failed_count(0); + for (int i = 0; i < _method_count; ++i) { + sofa::pbrpc::builtin::MethodStat* method_stat = stat_out->add_method_stats(); + LatestStats(i, slot_count, method_stat); + stat_out->set_succeed_count( + stat_out->succeed_count() + method_stat->succeed_count()); + stat_out->set_failed_count( + stat_out->failed_count() + method_stat->failed_count()); + } + } + +private: + void GetRealPeriod(int64 expect_period, int64* real_period, int* slot_count) + { + int sc = 1; + if (expect_period > 1) { + sc = (expect_period - 1) / STAT_SLOT_SECONDS + 1; + } + sc = std::min(sc, STAT_SLOT_COUNT - 2); + *real_period = sc * STAT_SLOT_SECONDS; + *slot_count = sc; + } + +private: + ServiceBoard* _next; + google::protobuf::Service* _svc; + bool _own; + const google::protobuf::ServiceDescriptor* _svc_desc; + int _method_count; + MethodBoard* _method_boards; +}; + +class ServicePool +{ +public: + ServicePool() : _head(NULL), _count(0) + { + memset(_cache, 0, sizeof(_cache)); + } + + virtual ~ServicePool() + { + for (ServiceMap::iterator it = _service_map.begin(); + it != _service_map.end(); ++it) { + delete it->second; + } + } + + bool RegisterService(google::protobuf::Service* service, bool take_ownership = true) + { + SCHECK(service != NULL); + const std::string& svc_name = service->GetDescriptor()->full_name(); + ScopedLocker _(_service_map_lock); + // check exist + if (_service_map.find(svc_name) != _service_map.end()) { + return false; + } + // register service + ServiceBoard* svc_board = new ServiceBoard(_head, service, take_ownership); + _service_map[svc_name] = svc_board; + _head = svc_board; + ++_count; + // add into cache + uint64 cache_index = CacheIndex(svc_name); + if (_cache[cache_index] == NULL) { + _cache[cache_index] = svc_board; + } + return true; + } + + ServiceBoard* FindService(const std::string& svc_name) + { + // find in cache first + uint64 cache_index = CacheIndex(svc_name); + if (_cache[cache_index] != NULL + && _cache[cache_index]->ServiceName() == svc_name) { + return _cache[cache_index]; + } + // find in map then + ScopedLocker _(_service_map_lock); + ServiceMap::iterator it = _service_map.find(svc_name); + return it == _service_map.end() ? NULL : it->second; + } + + // List registered services in order by name. + void ListService(std::list* svc_list) + { + SCHECK(svc_list != NULL); + svc_list->clear(); + // get services from link, and make them in order + ServiceBoard* sp = _head; + ServiceMap tmp_map; + while (sp != NULL) { + tmp_map[sp->ServiceName()] = sp; + sp = sp->Next(); + } + // copy to list + for (ServiceMap::iterator it = tmp_map.begin(); + it != tmp_map.end(); ++it) { + svc_list->push_back(it->second); + } + } + + // List registered services in order by name. + void ListService(std::list* svc_list) + { + SCHECK(svc_list != NULL); + svc_list->clear(); + std::list board_list; + ListService(&board_list); + for (std::list::iterator it = board_list.begin(); + it != board_list.end(); ++it) { + svc_list->push_back((*it)->Service()); + } + } + + void ListService(sofa::pbrpc::builtin::ListServiceResponse* response) + { + SCHECK(response != NULL); + response->Clear(); + // get services + std::list svc_list; + ListService(&svc_list); + // add to response + std::set added_file_set; + for (std::list::iterator it = svc_list.begin(); + it != svc_list.end(); ++it) + { + const google::protobuf::ServiceDescriptor* sd = (*it)->GetDescriptor(); + AddFileDescriptor(response, &added_file_set, sd->file()); + *(response->add_services()) = sd->full_name(); + } + } + + int ServiceCount() + { + return _count; + } + + void NextSlot() + { + ServiceBoard* sp = _head; + while (sp != NULL) { + sp->NextSlot(); + sp = sp->Next(); + } + } + +private: + uint64 CacheIndex(const std::string& name) + { + return murmurhash(name.c_str(), name.size()) % SERVICE_CACHE_SLOT_COUNT; + } + + void AddFileDescriptor(sofa::pbrpc::builtin::ListServiceResponse* response, + std::set* added_file_set, const google::protobuf::FileDescriptor* fd) + { + for (int i = 0; i < fd->dependency_count(); ++i) { + const google::protobuf::FileDescriptor* dfd = fd->dependency(i); + AddFileDescriptor(response, added_file_set, dfd); + } + if (added_file_set->find(fd->name()) == added_file_set->end()) { + google::protobuf::FileDescriptorProto* fdp = response->add_files(); + fd->CopyTo(fdp); + added_file_set->insert(fd->name()); + } + } + +private: + typedef std::map ServiceMap; + ServiceMap _service_map; + FastLock _service_map_lock; + + ServiceBoard* _head; + int _count; + ServiceBoard* _cache[SERVICE_CACHE_SLOT_COUNT]; + + SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(ServicePool); +}; // class ServicePool + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_SERVICE_POOL_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/smart_ptr/bad_weak_ptr.hpp b/src/sofa/pbrpc/smart_ptr/bad_weak_ptr.hpp new file mode 100644 index 0000000..146c9a6 --- /dev/null +++ b/src/sofa/pbrpc/smart_ptr/bad_weak_ptr.hpp @@ -0,0 +1,37 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from boost. +// +// Copyright Beman Dawes 2002, 2006 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/system + +#ifndef _SOFA_PBRPC_BAD_WEAK_PTR_ +#define _SOFA_PBRPC_BAD_WEAK_PTR_ + +#include + +namespace sofa { +namespace pbrpc { + +class bad_weak_ptr: public std::exception +{ +public: + virtual char const * what() const throw() + { + return "sofa::pbrpc::bad_weak_ptr"; + } +}; + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_BAD_WEAK_PTR_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/smart_ptr/checked_delete.hpp b/src/sofa/pbrpc/smart_ptr/checked_delete.hpp new file mode 100644 index 0000000..1c54250 --- /dev/null +++ b/src/sofa/pbrpc/smart_ptr/checked_delete.hpp @@ -0,0 +1,63 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from boost. +// +// Copyright Beman Dawes 2002, 2006 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/system + +#ifndef _SOFA_PBRPC_SMART_PTR_CHECKED_DELETE_ +#define _SOFA_PBRPC_SMART_PTR_CHECKED_DELETE_ + +namespace sofa { +namespace pbrpc { + +template +inline void checked_delete(T* px) +{ + typedef char type_must_be_complete[sizeof(T) ? 1 : -1 ]; + (void) sizeof(type_must_be_complete); + delete px; +} + +template inline void checked_array_delete(T * x) +{ + typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; + (void) sizeof(type_must_be_complete); + delete [] x; +} + +template struct checked_deleter +{ + typedef void result_type; + typedef T * argument_type; + + void operator()(T * x) const + { + ::sofa::pbrpc::checked_delete(x); + } +}; + +template struct checked_array_deleter +{ + typedef void result_type; + typedef T * argument_type; + + void operator()(T * x) const + { + ::sofa::pbrpc::checked_array_delete(x); + } +}; + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_SMART_PTR_CHECKED_DELETE_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/smart_ptr/detail/operator_bool.hpp b/src/sofa/pbrpc/smart_ptr/detail/operator_bool.hpp new file mode 100644 index 0000000..9d457fc --- /dev/null +++ b/src/sofa/pbrpc/smart_ptr/detail/operator_bool.hpp @@ -0,0 +1,28 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from boost. +// +// Copyright Beman Dawes 2002, 2006 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/system + + typedef T * (this_type::*unspecified_bool_type)() const; + + operator unspecified_bool_type() const // never throws + { + return px == 0 ? 0: &this_type::get; + } + + // operator! is redundant, but some compilers need it + bool operator! () const // never throws + { + return px == 0; + } + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/smart_ptr/detail/shared_count.hpp b/src/sofa/pbrpc/smart_ptr/detail/shared_count.hpp new file mode 100644 index 0000000..863b4ba --- /dev/null +++ b/src/sofa/pbrpc/smart_ptr/detail/shared_count.hpp @@ -0,0 +1,324 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from boost. +// +// Copyright Beman Dawes 2002, 2006 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/system + +#ifndef _SOFA_PBRPC_SMART_PTR_DETAIL_SHARED_COUNT_ +#define _SOFA_PBRPC_SMART_PTR_DETAIL_SHARED_COUNT_ + +#include +#include +#include +#include + +#include // std::less +#include // std::bad_alloc + +namespace sofa { +namespace pbrpc { +namespace detail { + +int const shared_count_id = 0x2C35F101; +int const weak_count_id = 0x298C38A4; + +struct sp_nothrow_tag {}; + +template< class D > struct sp_inplace_tag +{ +}; + +class weak_count; + +class shared_count +{ +private: + + sp_counted_base * pi_; + + friend class weak_count; + +public: + + shared_count(): pi_(0) // nothrow + { + } + + template explicit shared_count( Y * p ): pi_( 0 ) + { + try + { + pi_ = new sp_counted_impl_p( p ); + } + catch(...) + { + sofa::pbrpc::checked_delete( p ); + throw; + } + + } + + template shared_count( P p, D d ): pi_(0) + { + + try + { + pi_ = new sp_counted_impl_pd(p, d); + } + catch(...) + { + d(p); // delete p + throw; + } + + } + + template< class P, class D > shared_count( P p, sp_inplace_tag ): pi_( 0 ) + { + + try + { + pi_ = new sp_counted_impl_pd< P, D >( p ); + } + catch( ... ) + { + D()( p ); // delete p + throw; + } + + } + + template shared_count( P p, D d, A a ): pi_( 0 ) + { + typedef sp_counted_impl_pda impl_type; + typedef typename A::template rebind< impl_type >::other A2; + + A2 a2( a ); + + try + { + pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); + new( static_cast< void* >( pi_ ) ) impl_type( p, d, a ); + } + catch(...) + { + d( p ); + + if( pi_ != 0 ) + { + a2.deallocate( static_cast< impl_type* >( pi_ ), 1 ); + } + + throw; + } + + } + + template< class P, class D, class A > shared_count( P p, sp_inplace_tag< D >, A a ): pi_( 0 ) + { + typedef sp_counted_impl_pda< P, D, A > impl_type; + typedef typename A::template rebind< impl_type >::other A2; + + A2 a2( a ); + + try + { + pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); + new( static_cast< void* >( pi_ ) ) impl_type( p, a ); + } + catch(...) + { + D()( p ); + + if( pi_ != 0 ) + { + a2.deallocate( static_cast< impl_type* >( pi_ ), 1 ); + } + + throw; + } + + } + + ~shared_count() // nothrow + { + if( pi_ != 0 ) pi_->release(); + } + + shared_count(shared_count const & r): pi_(r.pi_) // nothrow + { + if( pi_ != 0 ) pi_->add_ref_copy(); + } + + explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0 + shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0 + + shared_count & operator= (shared_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + + if( tmp != pi_ ) + { + if( tmp != 0 ) tmp->add_ref_copy(); + if( pi_ != 0 ) pi_->release(); + pi_ = tmp; + } + + return *this; + } + + void swap(shared_count & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + r.pi_ = pi_; + pi_ = tmp; + } + + long use_count() const // nothrow + { + return pi_ != 0? pi_->use_count(): 0; + } + + bool unique() const // nothrow + { + return use_count() == 1; + } + + bool empty() const // nothrow + { + return pi_ == 0; + } + + friend inline bool operator==(shared_count const & a, shared_count const & b) + { + return a.pi_ == b.pi_; + } + + friend inline bool operator<(shared_count const & a, shared_count const & b) + { + return std::less()( a.pi_, b.pi_ ); + } + + void * get_deleter( std::type_info const & ti ) const + { + return pi_? pi_->get_deleter( ti ): 0; + } +}; + + +class weak_count +{ +private: + + sp_counted_base * pi_; + + friend class shared_count; + +public: + + weak_count(): pi_(0) // nothrow + { + } + + weak_count(shared_count const & r): pi_(r.pi_) // nothrow + { + if(pi_ != 0) pi_->weak_add_ref(); + } + + weak_count(weak_count const & r): pi_(r.pi_) // nothrow + { + if(pi_ != 0) pi_->weak_add_ref(); + } + + ~weak_count() // nothrow + { + if(pi_ != 0) pi_->weak_release(); + } + + weak_count & operator= (shared_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + + if( tmp != pi_ ) + { + if(tmp != 0) tmp->weak_add_ref(); + if(pi_ != 0) pi_->weak_release(); + pi_ = tmp; + } + + return *this; + } + + weak_count & operator= (weak_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + + if( tmp != pi_ ) + { + if(tmp != 0) tmp->weak_add_ref(); + if(pi_ != 0) pi_->weak_release(); + pi_ = tmp; + } + + return *this; + } + + void swap(weak_count & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + r.pi_ = pi_; + pi_ = tmp; + } + + long use_count() const // nothrow + { + return pi_ != 0? pi_->use_count(): 0; + } + + bool empty() const // nothrow + { + return pi_ == 0; + } + + friend inline bool operator==(weak_count const & a, weak_count const & b) + { + return a.pi_ == b.pi_; + } + + friend inline bool operator<(weak_count const & a, weak_count const & b) + { + return std::less()(a.pi_, b.pi_); + } +}; + +inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ ) +{ + if( pi_ == 0 || !pi_->add_ref_lock() ) + { + throw sofa::pbrpc::bad_weak_ptr(); + } +} + +inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ ) +{ + if( pi_ != 0 && !pi_->add_ref_lock() ) + { + pi_ = 0; + } +} + +} // namespace detail +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_SMART_PTR_DETAIL_SHARED_COUNT_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/smart_ptr/detail/sp_convertible.hpp b/src/sofa/pbrpc/smart_ptr/detail/sp_convertible.hpp new file mode 100644 index 0000000..9fe3e3b --- /dev/null +++ b/src/sofa/pbrpc/smart_ptr/detail/sp_convertible.hpp @@ -0,0 +1,58 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from boost. +// +// Copyright Beman Dawes 2002, 2006 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/system + +#ifndef _SOFA_PBRPC_SMART_PTR_DETAIL_SP_CONVERTIBLE_ +#define _SOFA_PBRPC_SMART_PTR_DETAIL_SP_CONVERTIBLE_ + +namespace sofa { +namespace pbrpc { +namespace detail { + +template< class Y, class T > struct sp_convertible +{ + typedef char (&yes) [1]; + typedef char (&no) [2]; + + static yes f( T* ); + static no f( ... ); + + enum _vt { value = sizeof( (f)( static_cast(0) ) ) == sizeof(yes) }; +}; + +struct sp_empty +{ +}; + +template< bool > struct sp_enable_if_convertible_impl; + +template<> struct sp_enable_if_convertible_impl +{ + typedef sp_empty type; +}; + +template<> struct sp_enable_if_convertible_impl +{ +}; + +template< class Y, class T > struct sp_enable_if_convertible: public sp_enable_if_convertible_impl< sp_convertible< Y, T >::value > +{ +}; + +} // namespace detail +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_SMART_PTR_DETAIL_SP_CONVERTIBLE_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/smart_ptr/detail/sp_counted_base.hpp b/src/sofa/pbrpc/smart_ptr/detail/sp_counted_base.hpp new file mode 100644 index 0000000..ce847ff --- /dev/null +++ b/src/sofa/pbrpc/smart_ptr/detail/sp_counted_base.hpp @@ -0,0 +1,22 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from boost. +// +// Copyright Beman Dawes 2002, 2006 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/system + +#ifndef _SOFA_PBRPC_SMART_PTR_DETAIL_SP_COUNTED_BASE_ +#define _SOFA_PBRPC_SMART_PTR_DETAIL_SP_COUNTED_BASE_ + +#include + +#endif // _SOFA_PBRPC_SMART_PTR_DETAIL_SP_COUNTED_BASE_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/smart_ptr/detail/sp_counted_base_gcc_x86.hpp b/src/sofa/pbrpc/smart_ptr/detail/sp_counted_base_gcc_x86.hpp new file mode 100644 index 0000000..b3fe717 --- /dev/null +++ b/src/sofa/pbrpc/smart_ptr/detail/sp_counted_base_gcc_x86.hpp @@ -0,0 +1,164 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from boost. +// +// Copyright Beman Dawes 2002, 2006 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/system + +#ifndef _SOFA_PBRPC_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_ +#define _SOFA_PBRPC_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_ + +#include + +namespace sofa { +namespace pbrpc { +namespace detail { + +inline int atomic_exchange_and_add( int * pw, int dv ) +{ + // int r = *pw; + // *pw += dv; + // return r; + + int r; + + __asm__ __volatile__ + ( + "lock\n\t" + "xadd %1, %0": + "=m"( *pw ), "=r"( r ): // outputs (%0, %1) + "m"( *pw ), "1"( dv ): // inputs (%2, %3 == %1) + "memory", "cc" // clobbers + ); + + return r; +} + +inline void atomic_increment( int * pw ) +{ + //atomic_exchange_and_add( pw, 1 ); + + __asm__ + ( + "lock\n\t" + "incl %0": + "=m"( *pw ): // output (%0) + "m"( *pw ): // input (%1) + "cc" // clobbers + ); +} + +inline int atomic_conditional_increment( int * pw ) +{ + // int rv = *pw; + // if( rv != 0 ) ++*pw; + // return rv; + + int rv, tmp; + + __asm__ + ( + "movl %0, %%eax\n\t" + "0:\n\t" + "test %%eax, %%eax\n\t" + "je 1f\n\t" + "movl %%eax, %2\n\t" + "incl %2\n\t" + "lock\n\t" + "cmpxchgl %2, %0\n\t" + "jne 0b\n\t" + "1:": + "=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2) + "m"( *pw ): // input (%3) + "cc" // clobbers + ); + + return rv; +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( std::type_info const & ti ) = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_exchange_and_add( &use_count_, -1 ) == 1 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); + } +}; + +} // namespace detail +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/smart_ptr/detail/sp_counted_impl.hpp b/src/sofa/pbrpc/smart_ptr/detail/sp_counted_impl.hpp new file mode 100644 index 0000000..35aef6d --- /dev/null +++ b/src/sofa/pbrpc/smart_ptr/detail/sp_counted_impl.hpp @@ -0,0 +1,170 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from boost. +// +// Copyright Beman Dawes 2002, 2006 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/system + +#ifndef _SOFA_PBRPC_SMART_PTR_DETAIL_SP_COUNTED_IMPL_ +#define _SOFA_PBRPC_SMART_PTR_DETAIL_SP_COUNTED_IMPL_ + +#include +#include + +#include // std::allocator +#include // std::size_t +#include // std::type_info + +namespace sofa { +namespace pbrpc { +namespace detail { + +template class sp_counted_impl_p: public sp_counted_base +{ +private: + + X * px_; + + sp_counted_impl_p( sp_counted_impl_p const & ); + sp_counted_impl_p & operator= ( sp_counted_impl_p const & ); + + typedef sp_counted_impl_p this_type; + +public: + + explicit sp_counted_impl_p( X * px ): px_( px ) + { + } + + virtual void dispose() // nothrow + { + sofa::pbrpc::checked_delete( px_ ); + } + + virtual void * get_deleter( std::type_info const & ) + { + return 0; + } + + + void * operator new( std::size_t ) + { + return std::allocator().allocate( 1, static_cast(0) ); + } + + void operator delete( void * p ) + { + std::allocator().deallocate( static_cast(p), 1 ); + } + + +}; + + +template class sp_counted_impl_pd: public sp_counted_base +{ +private: + + P ptr; // copy constructor must not throw + D del; // copy constructor must not throw + + sp_counted_impl_pd( sp_counted_impl_pd const & ); + sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & ); + + typedef sp_counted_impl_pd this_type; + +public: + + // pre: d(p) must not throw + + sp_counted_impl_pd( P p, D & d ): ptr( p ), del( d ) + { + } + + sp_counted_impl_pd( P p ): ptr( p ), del() + { + } + + virtual void dispose() // nothrow + { + del( ptr ); + } + + virtual void * get_deleter( std::type_info const & ti ) + { + return ti == typeid(D) ? &reinterpret_cast( del ): 0; + } + + + void * operator new( std::size_t ) + { + return std::allocator().allocate( 1, static_cast(0) ); + } + + void operator delete( void * p ) + { + std::allocator().deallocate( static_cast(p), 1 ); + } + +}; + +template class sp_counted_impl_pda: public sp_counted_base +{ +private: + + P p_; // copy constructor must not throw + D d_; // copy constructor must not throw + A a_; // copy constructor must not throw + + sp_counted_impl_pda( sp_counted_impl_pda const & ); + sp_counted_impl_pda & operator= ( sp_counted_impl_pda const & ); + + typedef sp_counted_impl_pda this_type; + +public: + + // pre: d( p ) must not throw + + sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( d ), a_( a ) + { + } + + sp_counted_impl_pda( P p, A a ): p_( p ), d_(), a_( a ) + { + } + + virtual void dispose() // nothrow + { + d_( p_ ); + } + + virtual void destroy() // nothrow + { + typedef typename A::template rebind< this_type >::other A2; + + A2 a2( a_ ); + + this->~this_type(); + a2.deallocate( this, 1 ); + } + + virtual void * get_deleter( std::type_info const & ti ) + { + return ti == typeid(D) ? &reinterpret_cast( d_ ): 0; + } +}; + +} // namespace detail +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_SMART_PTR_DETAIL_SP_COUNTED_IMPL_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/smart_ptr/detail/spinlock.hpp b/src/sofa/pbrpc/smart_ptr/detail/spinlock.hpp new file mode 100644 index 0000000..87fb7d2 --- /dev/null +++ b/src/sofa/pbrpc/smart_ptr/detail/spinlock.hpp @@ -0,0 +1,22 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from boost. +// +// Copyright Beman Dawes 2002, 2006 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/system + +#ifndef _SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_ +#define _SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_ + +#include + +#endif // _SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/smart_ptr/detail/spinlock_pool.hpp b/src/sofa/pbrpc/smart_ptr/detail/spinlock_pool.hpp new file mode 100644 index 0000000..3c59756 --- /dev/null +++ b/src/sofa/pbrpc/smart_ptr/detail/spinlock_pool.hpp @@ -0,0 +1,88 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from boost. +// +// Copyright Beman Dawes 2002, 2006 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/system + +#ifndef _SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_POOL_ +#define _SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_POOL_ + +// +// spinlock_pool<0> is reserved for atomic<>, when/if it arrives +// spinlock_pool<1> is reserved for shared_ptr reference counts +// spinlock_pool<2> is reserved for shared_ptr atomic access +// + +#include + +#include + +namespace sofa { +namespace pbrpc { +namespace detail { + +template< int I > class spinlock_pool +{ +private: + + static spinlock pool_[ 41 ]; + +public: + + static spinlock & spinlock_for( void const * pv ) + { + std::size_t i = reinterpret_cast< std::size_t >( pv ) % 41; + return pool_[ i ]; + } + + class scoped_lock + { + private: + + spinlock & sp_; + + scoped_lock( scoped_lock const & ); + scoped_lock & operator=( scoped_lock const & ); + + public: + + explicit scoped_lock( void const * pv ): sp_( spinlock_for( pv ) ) + { + sp_.lock(); + } + + ~scoped_lock() + { + sp_.unlock(); + } + }; +}; + +template< int I > spinlock spinlock_pool< I >::pool_[ 41 ] = +{ + SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, + SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, + SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, + SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, + SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, + SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, + SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, + SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT, + SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT +}; + +} // namespace detail +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_POOL_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/smart_ptr/detail/spinlock_pt.hpp b/src/sofa/pbrpc/smart_ptr/detail/spinlock_pt.hpp new file mode 100644 index 0000000..6fcd98a --- /dev/null +++ b/src/sofa/pbrpc/smart_ptr/detail/spinlock_pt.hpp @@ -0,0 +1,80 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from boost. +// +// Copyright Beman Dawes 2002, 2006 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/system + +#ifndef _SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_PT_ +#define _SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_PT_ + +#include + +namespace sofa { +namespace pbrpc { +namespace detail { + +class spinlock +{ +public: + + pthread_mutex_t v_; + +public: + + bool try_lock() + { + return pthread_mutex_trylock( &v_ ) == 0; + } + + void lock() + { + pthread_mutex_lock( &v_ ); + } + + void unlock() + { + pthread_mutex_unlock( &v_ ); + } + +public: + + class scoped_lock + { + private: + + spinlock & sp_; + + scoped_lock( scoped_lock const & ); + scoped_lock & operator=( scoped_lock const & ); + + public: + + explicit scoped_lock( spinlock & sp ): sp_( sp ) + { + sp.lock(); + } + + ~scoped_lock() + { + sp_.unlock(); + } + }; +}; + +} // namespace detail +} // namespace pbrpc +} // namespace sofa + +#define SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT { PTHREAD_MUTEX_INITIALIZER } + +#endif // _SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_PT_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/smart_ptr/enable_shared_from_this.hpp b/src/sofa/pbrpc/smart_ptr/enable_shared_from_this.hpp new file mode 100644 index 0000000..9acc550 --- /dev/null +++ b/src/sofa/pbrpc/smart_ptr/enable_shared_from_this.hpp @@ -0,0 +1,82 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from boost. +// +// Copyright Beman Dawes 2002, 2006 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/system + +#ifndef _SOFA_PBRPC_SMART_PTR_ENABLE_SHARED_FROM_THIS_ +#define _SOFA_PBRPC_SMART_PTR_ENABLE_SHARED_FROM_THIS_ + +#include +#include + +namespace sofa { +namespace pbrpc { + +template class enable_shared_from_this +{ +protected: + + enable_shared_from_this() + { + } + + enable_shared_from_this(enable_shared_from_this const &) + { + } + + enable_shared_from_this & operator=(enable_shared_from_this const &) + { + return *this; + } + + ~enable_shared_from_this() + { + } + +public: + + shared_ptr shared_from_this() + { + shared_ptr p( weak_this_ ); + assert( p.get() == this ); + return p; + } + + shared_ptr shared_from_this() const + { + shared_ptr p( weak_this_ ); + assert( p.get() == this ); + return p; + } + +public: // actually private, but avoids compiler template friendship issues + + // Note: invoked automatically by shared_ptr; do not call + template void _internal_accept_owner( shared_ptr const * ppx, Y * py ) const + { + if( weak_this_.expired() ) + { + weak_this_ = shared_ptr( *ppx, py ); + } + } + +private: + + mutable weak_ptr weak_this_; +}; + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_SMART_PTR_ENABLE_SHARED_FROM_THIS_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/smart_ptr/memory_order.hpp b/src/sofa/pbrpc/smart_ptr/memory_order.hpp new file mode 100644 index 0000000..358a08a --- /dev/null +++ b/src/sofa/pbrpc/smart_ptr/memory_order.hpp @@ -0,0 +1,53 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from boost. +// +// Copyright Beman Dawes 2002, 2006 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/system + +#ifndef _SOFA_PBRPC_SMART_PTR_MEMORY_ORDER_ +#define _SOFA_PBRPC_SMART_PTR_MEMORY_ORDER_ + +namespace sofa { +namespace pbrpc { + +// +// Enum values are chosen so that code that needs to insert +// a trailing fence for acquire semantics can use a single +// test such as: +// +// if( mo & memory_order_acquire ) { ...fence... } +// +// For leading fences one can use: +// +// if( mo & memory_order_release ) { ...fence... } +// +// Architectures such as Alpha that need a fence on consume +// can use: +// +// if( mo & ( memory_order_acquire | memory_order_consume ) ) { ...fence... } +// + +enum memory_order +{ + memory_order_relaxed = 0, + memory_order_acquire = 1, + memory_order_release = 2, + memory_order_acq_rel = 3, // acquire | release + memory_order_seq_cst = 7, // acq_rel | 4 + memory_order_consume = 8 +}; + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_SMART_PTR_MEMORY_ORDER_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/smart_ptr/owner_less.hpp b/src/sofa/pbrpc/smart_ptr/owner_less.hpp new file mode 100644 index 0000000..d5596b0 --- /dev/null +++ b/src/sofa/pbrpc/smart_ptr/owner_less.hpp @@ -0,0 +1,63 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from boost. +// +// Copyright Beman Dawes 2002, 2006 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/system + +#ifndef _SOFA_PBRPC_SMART_PTR_OWNER_LESS_ +#define _SOFA_PBRPC_SMART_PTR_OWNER_LESS_ + +#include + +namespace sofa { +namespace pbrpc { + + template class shared_ptr; + template class weak_ptr; + + namespace detail + { + template + struct generic_owner_less : public std::binary_function + { + bool operator()(const T &lhs, const T &rhs) const + { + return lhs.owner_before(rhs); + } + bool operator()(const T &lhs, const U &rhs) const + { + return lhs.owner_before(rhs); + } + bool operator()(const U &lhs, const T &rhs) const + { + return lhs.owner_before(rhs); + } + }; + } // namespace detail + + template struct owner_less; + + template + struct owner_less >: + public detail::generic_owner_less, weak_ptr > + {}; + + template + struct owner_less >: + public detail::generic_owner_less, shared_ptr > + {}; + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_SMART_PTR_OWNER_LESS_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/smart_ptr/scoped_ptr.hpp b/src/sofa/pbrpc/smart_ptr/scoped_ptr.hpp new file mode 100644 index 0000000..e0cbf68 --- /dev/null +++ b/src/sofa/pbrpc/smart_ptr/scoped_ptr.hpp @@ -0,0 +1,103 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from boost. +// +// Copyright Beman Dawes 2002, 2006 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/system + +#ifndef _SOFA_PBRPC_SMART_PTR_SCOPED_PTR_ +#define _SOFA_PBRPC_SMART_PTR_SCOPED_PTR_ + +#include + +namespace sofa { +namespace pbrpc { + +// scoped_ptr mimics a built-in pointer except that it guarantees deletion +// of the object pointed to, either on destruction of the scoped_ptr or via +// an explicit reset(). scoped_ptr is a simple solution for simple needs; +// use shared_ptr or std::auto_ptr if your needs are more complex. + +template class scoped_ptr // noncopyable +{ +private: + + T * px; + + scoped_ptr(scoped_ptr const &); + scoped_ptr & operator=(scoped_ptr const &); + + typedef scoped_ptr this_type; + + void operator==( scoped_ptr const& ) const; + void operator!=( scoped_ptr const& ) const; + +public: + + typedef T element_type; + + explicit scoped_ptr( T * p = 0 ): px( p ) // never throws + { + } + + ~scoped_ptr() // never throws + { + sofa::pbrpc::checked_delete( px ); + } + + void reset(T * p = 0) // never throws + { + this_type(p).swap(*this); + } + + T & operator*() const // never throws + { + return *px; + } + + T * operator->() const // never throws + { + return px; + } + + T * get() const // never throws + { + return px; + } + +// implicit conversion to "bool" +#include + + void swap(scoped_ptr & b) // never throws + { + T * tmp = b.px; + b.px = px; + px = tmp; + } +}; + +template inline void swap(scoped_ptr & a, scoped_ptr & b) // never throws +{ + a.swap(b); +} + +// get_pointer(p) is a generic way to say p.get() + +template inline T * get_pointer(scoped_ptr const & p) +{ + return p.get(); +} + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_SMART_PTR_SCOPED_PTR_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/smart_ptr/shared_ptr.hpp b/src/sofa/pbrpc/smart_ptr/shared_ptr.hpp new file mode 100644 index 0000000..3e3066c --- /dev/null +++ b/src/sofa/pbrpc/smart_ptr/shared_ptr.hpp @@ -0,0 +1,476 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from boost. +// +// Copyright Beman Dawes 2002, 2006 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/system + +#ifndef _SOFA_PBRPC_SMART_PTR_SHARED_PTR_ +#define _SOFA_PBRPC_SMART_PTR_SHARED_PTR_ + +#include +#include +#include +#include +#include + +#include // for std::swap +#include // for std::less +#include // for std::bad_cast +#include // for std::size_t +#include // for std::basic_ostream +#include +#include + +namespace sofa { +namespace pbrpc { + +template class shared_ptr; +template class weak_ptr; +template class enable_shared_from_this; +template class enable_shared_from_this2; + +namespace detail +{ + +struct static_cast_tag {}; +struct const_cast_tag {}; +struct dynamic_cast_tag {}; +struct polymorphic_cast_tag {}; + +template struct shared_ptr_traits +{ + typedef T & reference; +}; + +template<> struct shared_ptr_traits +{ + typedef void reference; +}; + +template<> struct shared_ptr_traits +{ + typedef void reference; +}; + +template<> struct shared_ptr_traits +{ + typedef void reference; +}; + +template<> struct shared_ptr_traits +{ + typedef void reference; +}; + + +// enable_shared_from_this support + +template< class X, class Y, class T > +inline void sp_enable_shared_from_this( sofa::pbrpc::shared_ptr const * ppx, Y const * py, sofa::pbrpc::enable_shared_from_this< T > const * pe ) +{ + if( pe != 0 ) + { + pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) ); + } +} + +template< class X, class Y, class T > +inline void sp_enable_shared_from_this( sofa::pbrpc::shared_ptr * ppx, Y const * py, sofa::pbrpc::enable_shared_from_this2< T > const * pe ) +{ + if( pe != 0 ) + { + pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) ); + } +} + + +struct sp_any_pointer +{ + template sp_any_pointer( T* ) {} +}; + +inline void sp_enable_shared_from_this( sp_any_pointer, sp_any_pointer, sp_any_pointer ) +{ +} + + +} // namespace detail + + +// +// shared_ptr +// +// An enhanced relative of scoped_ptr with reference counted copy semantics. +// The object pointed to is deleted when the last shared_ptr pointing to it +// is destroyed or reset. +// + +template class shared_ptr +{ +private: + + typedef shared_ptr this_type; + +public: + + typedef T element_type; + typedef T value_type; + typedef T * pointer; + typedef typename sofa::pbrpc::detail::shared_ptr_traits::reference reference; + + shared_ptr(): px(0), pn() // never throws in 1.30+ + { + } + + template + explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete + { + sofa::pbrpc::detail::sp_enable_shared_from_this( this, p, p ); + } + + // + // Requirements: D's copy constructor must not throw + // + // shared_ptr will release p by calling d(p) + // + + template shared_ptr(Y * p, D d): px(p), pn(p, d) + { + sofa::pbrpc::detail::sp_enable_shared_from_this( this, p, p ); + } + + // As above, but with allocator. A's copy constructor shall not throw. + + template shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a ) + { + sofa::pbrpc::detail::sp_enable_shared_from_this( this, p, p ); + } + +// generated copy constructor, destructor are fine... + + template + explicit shared_ptr(weak_ptr const & r): pn(r.pn) // may throw + { + // it is now safe to copy r.px, as pn(r.pn) did not throw + px = r.px; + } + + template + shared_ptr( weak_ptr const & r, sofa::pbrpc::detail::sp_nothrow_tag ): px( 0 ), pn( r.pn, sofa::pbrpc::detail::sp_nothrow_tag() ) // never throws + { + if( !pn.empty() ) + { + px = r.px; + } + } + + template + shared_ptr( shared_ptr const & r, typename sofa::pbrpc::detail::sp_enable_if_convertible::type = sofa::pbrpc::detail::sp_empty() ) + : px( r.px ), pn( r.pn ) // never throws + { + } + + // aliasing + template< class Y > + shared_ptr( shared_ptr const & r, T * p ): px( p ), pn( r.pn ) // never throws + { + } + + template + shared_ptr(shared_ptr const & r, sofa::pbrpc::detail::static_cast_tag): px(static_cast(r.px)), pn(r.pn) + { + } + + template + shared_ptr(shared_ptr const & r, sofa::pbrpc::detail::const_cast_tag): px(const_cast(r.px)), pn(r.pn) + { + } + + template + shared_ptr(shared_ptr const & r, sofa::pbrpc::detail::dynamic_cast_tag): px(dynamic_cast(r.px)), pn(r.pn) + { + if(px == 0) // need to allocate new counter -- the cast failed + { + pn = sofa::pbrpc::detail::shared_count(); + } + } + + template + shared_ptr(shared_ptr const & r, sofa::pbrpc::detail::polymorphic_cast_tag): px(dynamic_cast(r.px)), pn(r.pn) + { + if(px == 0) + { + throw std::bad_cast(); + } + } + + // assignment + + shared_ptr & operator=( shared_ptr const & r ) // never throws + { + this_type(r).swap(*this); + return *this; + } + + template + shared_ptr & operator=(shared_ptr const & r) // never throws + { + this_type(r).swap(*this); + return *this; + } + + + + void reset() // never throws in 1.30+ + { + this_type().swap(*this); + } + + template void reset(Y * p) // Y must be complete + { + assert(p == 0 || p != px); // catch self-reset errors + this_type(p).swap(*this); + } + + template void reset( Y * p, D d ) + { + this_type( p, d ).swap( *this ); + } + + template void reset( Y * p, D d, A a ) + { + this_type( p, d, a ).swap( *this ); + } + + template void reset( shared_ptr const & r, T * p ) + { + this_type( r, p ).swap( *this ); + } + + reference operator* () const // never throws + { + assert(px != 0); + return *px; + } + + T * operator-> () const // never throws + { + assert(px != 0); + return px; + } + + T * get() const // never throws + { + return px; + } + +// implicit conversion to "bool" +#include + + bool unique() const // never throws + { + return pn.unique(); + } + + long use_count() const // never throws + { + return pn.use_count(); + } + + void swap(shared_ptr & other) // never throws + { + std::swap(px, other.px); + pn.swap(other.pn); + } + + template bool owner_before( shared_ptr const & rhs ) const + { + return pn < rhs.pn; + } + + template bool owner_before( weak_ptr const & rhs ) const + { + return pn < rhs.pn; + } + + void * _internal_get_deleter( std::type_info const & ti ) const + { + return pn.get_deleter( ti ); + } + + bool _internal_equiv( shared_ptr const & r ) const + { + return px == r.px && pn == r.pn; + } + + +private: + + template friend class shared_ptr; + template friend class weak_ptr; + + T * px; // contained pointer + sofa::pbrpc::detail::shared_count pn; // reference counter + +}; // shared_ptr + +template inline bool operator==(shared_ptr const & a, shared_ptr const & b) +{ + return a.get() == b.get(); +} + +template inline bool operator!=(shared_ptr const & a, shared_ptr const & b) +{ + return a.get() != b.get(); +} + +template inline bool operator<(shared_ptr const & a, shared_ptr const & b) +{ + return a.owner_before( b ); +} + +template inline void swap(shared_ptr & a, shared_ptr & b) +{ + a.swap(b); +} + +template shared_ptr static_pointer_cast(shared_ptr const & r) +{ + return shared_ptr(r, sofa::pbrpc::detail::static_cast_tag()); +} + +template shared_ptr const_pointer_cast(shared_ptr const & r) +{ + return shared_ptr(r, sofa::pbrpc::detail::const_cast_tag()); +} + +template shared_ptr dynamic_pointer_cast(shared_ptr const & r) +{ + return shared_ptr(r, sofa::pbrpc::detail::dynamic_cast_tag()); +} + +// get_pointer() enables boost::mem_fn to recognize shared_ptr + +template inline T * get_pointer(shared_ptr const & p) +{ + return p.get(); +} + +// operator<< + + +template std::ostream & operator<< (std::ostream & os, shared_ptr const & p) +{ + os << p.get(); + return os; +} + +template std::basic_ostream & operator<< (std::basic_ostream & os, shared_ptr const & p) +{ + os << p.get(); + return os; +} + +// get_deleter + +template D * get_deleter(shared_ptr const & p) +{ + void const * q = p._internal_get_deleter(typeid(D)); + return const_cast(static_cast(q)); +} + + +template inline bool atomic_is_lock_free( shared_ptr const * /*p*/ ) +{ + return false; +} + +template shared_ptr atomic_load( shared_ptr const * p ) +{ + sofa::pbrpc::detail::spinlock_pool<2>::scoped_lock lock( p ); + return *p; +} + +template inline shared_ptr atomic_load_explicit( shared_ptr const * p, ::sofa::pbrpc::memory_order /*mo*/ ) +{ + return atomic_load( p ); +} + +template void atomic_store( shared_ptr * p, shared_ptr r ) +{ + sofa::pbrpc::detail::spinlock_pool<2>::scoped_lock lock( p ); + p->swap( r ); +} + +template inline void atomic_store_explicit( shared_ptr * p, shared_ptr r, ::sofa::pbrpc::memory_order /*mo*/ ) +{ + atomic_store( p, r ); // std::move( r ) +} + +template shared_ptr atomic_exchange( shared_ptr * p, shared_ptr r ) +{ + sofa::pbrpc::detail::spinlock & sp = sofa::pbrpc::detail::spinlock_pool<2>::spinlock_for( p ); + + sp.lock(); + p->swap( r ); + sp.unlock(); + + return r; // return std::move( r ) +} + +template shared_ptr atomic_exchange_explicit( shared_ptr * p, shared_ptr r, ::sofa::pbrpc::memory_order /*mo*/ ) +{ + return atomic_exchange( p, r ); // std::move( r ) +} + +template bool atomic_compare_exchange( shared_ptr * p, shared_ptr * v, shared_ptr w ) +{ + sofa::pbrpc::detail::spinlock & sp = sofa::pbrpc::detail::spinlock_pool<2>::spinlock_for( p ); + + sp.lock(); + + if( p->_internal_equiv( *v ) ) + { + p->swap( w ); + + sp.unlock(); + + return true; + } + else + { + shared_ptr tmp( *p ); + + sp.unlock(); + + tmp.swap( *v ); + return false; + } +} + +template inline bool atomic_compare_exchange_explicit( shared_ptr * p, shared_ptr * v, shared_ptr w, ::sofa::pbrpc::memory_order /*success*/, ::sofa::pbrpc::memory_order /*failure*/ ) +{ + return atomic_compare_exchange( p, v, w ); // std::move( w ) +} + +// hash_value + +template< class T > std::size_t hash_value( sofa::pbrpc::shared_ptr const & p ) +{ + return reinterpret_cast(p.get()); +} + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_SMART_PTR_SHARED_PTR_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/smart_ptr/smart_ptr.hpp b/src/sofa/pbrpc/smart_ptr/smart_ptr.hpp new file mode 100644 index 0000000..16c3fdc --- /dev/null +++ b/src/sofa/pbrpc/smart_ptr/smart_ptr.hpp @@ -0,0 +1,21 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from boost. +// +// Copyright Beman Dawes 2002, 2006 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/system + +#include +#include +#include +#include +#include + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/smart_ptr/weak_ptr.hpp b/src/sofa/pbrpc/smart_ptr/weak_ptr.hpp new file mode 100644 index 0000000..f69d979 --- /dev/null +++ b/src/sofa/pbrpc/smart_ptr/weak_ptr.hpp @@ -0,0 +1,144 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +// This file is modified from boost. +// +// Copyright Beman Dawes 2002, 2006 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/system + +#ifndef _SOFA_PBRPC_SMART_PTR_WEAK_PTR_ +#define _SOFA_PBRPC_SMART_PTR_WEAK_PTR_ + +#include +#include + +namespace sofa { +namespace pbrpc { + +template +class weak_ptr +{ +private: + + typedef weak_ptr this_type; + +public: + + typedef T element_type; + + weak_ptr(): px(0), pn() // never throws in 1.30+ + { + } + + +// +// The "obvious" converting constructor implementation: +// +// template +// weak_ptr(weak_ptr const & r): px(r.px), pn(r.pn) // never throws +// { +// } +// +// has a serious problem. +// +// r.px may already have been invalidated. The px(r.px) +// conversion may require access to *r.px (virtual inheritance). +// +// It is not possible to avoid spurious access violations since +// in multithreaded programs r.px may be invalidated at any point. +// + + template + weak_ptr( weak_ptr const & r, typename sofa::pbrpc::detail::sp_enable_if_convertible::type = sofa::pbrpc::detail::sp_empty() ) + : px(r.lock().get()), pn(r.pn) // never throws + { + } + + + template + weak_ptr( shared_ptr const & r, typename sofa::pbrpc::detail::sp_enable_if_convertible::type = sofa::pbrpc::detail::sp_empty() ) + : px( r.px ), pn( r.pn ) // never throws + { + } + + + shared_ptr lock() const // never throws + { + return shared_ptr( *this, sofa::pbrpc::detail::sp_nothrow_tag() ); + } + + long use_count() const // never throws + { + return pn.use_count(); + } + + bool expired() const // never throws + { + return pn.use_count() == 0; + } + + bool _empty() const // extension, not in std::weak_ptr + { + return pn.empty(); + } + + void reset() // never throws in 1.30+ + { + this_type().swap(*this); + } + + void swap(this_type & other) // never throws + { + std::swap(px, other.px); + pn.swap(other.pn); + } + + void _internal_assign(T * px2, sofa::pbrpc::detail::shared_count const & pn2) + { + px = px2; + pn = pn2; + } + + template bool owner_before( weak_ptr const & rhs ) const + { + return pn < rhs.pn; + } + + template bool owner_before( shared_ptr const & rhs ) const + { + return pn < rhs.pn; + } + + +private: + + template friend class weak_ptr; + template friend class shared_ptr; + + T * px; // contained pointer + sofa::pbrpc::detail::weak_count pn; // reference counter + +}; // weak_ptr + +template inline bool operator<(weak_ptr const & a, weak_ptr const & b) +{ + return a.owner_before( b ); +} + +template void swap(weak_ptr & a, weak_ptr & b) +{ + a.swap(b); +} + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_SMART_PTR_WEAK_PTR_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/spin_lock.h b/src/sofa/pbrpc/spin_lock.h new file mode 100644 index 0000000..ac1a57b --- /dev/null +++ b/src/sofa/pbrpc/spin_lock.h @@ -0,0 +1,32 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_SPIN_LOCK_H_ +#define _SOFA_PBRPC_SPIN_LOCK_H_ + +#include + +namespace sofa { +namespace pbrpc { +class SpinLock +{ +public: + SpinLock() { pthread_spin_init(&_lock, 0); } + ~SpinLock() { pthread_spin_destroy(&_lock); } + void lock() { pthread_spin_lock(&_lock); } + bool try_lock() { return pthread_spin_trylock(&_lock) == 0; } + void unlock() { pthread_spin_unlock(&_lock); } + +private: + pthread_spinlock_t _lock; +}; // class SpinLock + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_SPIN_LOCK_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/string_utils.cc b/src/sofa/pbrpc/string_utils.cc new file mode 100644 index 0000000..a5c3a22 --- /dev/null +++ b/src/sofa/pbrpc/string_utils.cc @@ -0,0 +1,82 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include // for sprintf() + +#include +#include + +namespace sofa { +namespace pbrpc { + +int CEscapeInternal(const char* src, int src_len, char* dest, int dest_len) +{ + int used = 0; + const char* src_end = src + src_len; + for (; src < src_end; src++) + { + if (dest_len - used < 2) // at least two chars needed. + { + return -1; + } + switch (*src) + { + case '\a': dest[used++] = '\\'; dest[used++] = 'a'; break; + case '\b': dest[used++] = '\\'; dest[used++] = 'b'; break; + case '\f': dest[used++] = '\\'; dest[used++] = 'f'; break; + case '\n': dest[used++] = '\\'; dest[used++] = 'n'; break; + case '\r': dest[used++] = '\\'; dest[used++] = 'r'; break; + case '\t': dest[used++] = '\\'; dest[used++] = 't'; break; + case '\v': dest[used++] = '\\'; dest[used++] = 'v'; break; + case '\"': dest[used++] = '\\'; dest[used++] = '\"'; break; + case '\?': dest[used++] = '\\'; dest[used++] = '\?'; break; + case '\'': dest[used++] = '\\'; dest[used++] = '\''; break; + case '\\': dest[used++] = '\\'; dest[used++] = '\\'; break; + default: + if (Ascii::IsPrint(*src)) + { + dest[used++] = *src; + } + else + { + if (dest_len - used < 4) + return -1; + sprintf(dest + used, "\\x%02x", static_cast(*src)); + used += 4; + } + } + } + if (dest_len - used < 1) + return -1; + dest[used] = '\0'; + return used; +} + +int CEscapeString(const char* src, int src_len, char* dest, int dest_len) +{ + return CEscapeInternal(src, src_len, dest, dest_len); +} + +std::string CEscapeString(const char* src, int src_len) +{ + const int dest_length = src_len * 4 + 1; // Maximum space needed + char* dest = new char[dest_length]; + const int len = CEscapeInternal(src, src_len, dest, dest_length); + std::string str; + if (len >= 0) + str = dest; + return str; +} + +std::string CEscapeString(const std::string& src) +{ + return CEscapeString(src.data(), src.length()); +} + +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/string_utils.h b/src/sofa/pbrpc/string_utils.h new file mode 100644 index 0000000..c64634b --- /dev/null +++ b/src/sofa/pbrpc/string_utils.h @@ -0,0 +1,26 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_STRING_UTILS_H_ +#define _SOFA_PBRPC_STRING_UTILS_H_ + +#include + +namespace sofa { +namespace pbrpc { + +int CEscapeString(const char* src, int src_len, char* dest, int dest_len); + +std::string CEscapeString(const char* src, int src_len); + +std::string CEscapeString(const std::string& src); + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_STRING_UTILS_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/thread_group.cc b/src/sofa/pbrpc/thread_group.cc new file mode 100644 index 0000000..6ad7c78 --- /dev/null +++ b/src/sofa/pbrpc/thread_group.cc @@ -0,0 +1,53 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include +#include + +namespace sofa { +namespace pbrpc { + +ThreadGroup::ThreadGroup(int thread_num) +{ + _imp.reset(new ThreadGroupImpl(thread_num)); + _imp->start(); +} + +ThreadGroup::~ThreadGroup() +{ + _imp->stop(); + _imp.reset(); +} + +int ThreadGroup::thread_num() const +{ + return _imp->thread_num(); +} + +void ThreadGroup::dispatch(google::protobuf::Closure* handle) +{ + _imp->dispatch(handle); +} + +void ThreadGroup::post(google::protobuf::Closure* handle) +{ + _imp->post(handle); +} + +void ThreadGroup::dispatch(ExtClosure* handle) +{ + _imp->dispatch(handle); +} + +void ThreadGroup::post(ExtClosure* handle) +{ + _imp->post(handle); +} + +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/thread_group.h b/src/sofa/pbrpc/thread_group.h new file mode 100644 index 0000000..ec1d2d7 --- /dev/null +++ b/src/sofa/pbrpc/thread_group.h @@ -0,0 +1,74 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_THREAD_GROUP_H_ +#define _SOFA_PBRPC_THREAD_GROUP_H_ + +#include +#include + +namespace sofa { +namespace pbrpc { + +// Defined in this file. +class ThreadGroup; +typedef sofa::pbrpc::shared_ptr ThreadGroupPtr; + +// Defined in other files. +class ThreadGroupImpl; + +class ThreadGroup +{ +public: + // Constructor. User should specify the "thread_num", which can not be + // changed afterwards. User can optionally give a "name", which may be used + // as key of the thread group. All the threads will start running after + // contruct done. + ThreadGroup(int thread_num); + + // Destructor. It will join all threads, so user must ensure that all threads + // will exit eventually. + ~ThreadGroup(); + + // Get the number of threads in this thread group. + int thread_num() const; + + // Request the thread group to invoke the given handler. + // The handler may be executed inside this function if the guarantee can be met. + // The "handler" should be a self delete closure, which can be created through + // NewClosure(). + void dispatch(google::protobuf::Closure* handler); + + // Request the thread group to invoke the given handler and return immediately. + // It guarantees that the handler will not be called from inside this function. + // The "handler" should be a self delete closure, which can be created through + // NewClosure(). + void post(google::protobuf::Closure* handler); + + // Request the thread group to invoke the given handler. + // The handler may be executed inside this function if the guarantee can be met. + // The "handler" should be a self delete closure, which can be created through + // NewExtClosure(). + void dispatch(ExtClosure* handler); + + // Request the thread group to invoke the given handler and return immediately. + // It guarantees that the handler will not be called from inside this function. + // The "handler" should be a self delete closure, which can be created through + // NewExtClosure(). + void post(ExtClosure* handler); + +private: + sofa::pbrpc::shared_ptr _imp; + + SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(ThreadGroup); +}; + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_THREAD_GROUP_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/thread_group_impl.h b/src/sofa/pbrpc/thread_group_impl.h new file mode 100644 index 0000000..a82d851 --- /dev/null +++ b/src/sofa/pbrpc/thread_group_impl.h @@ -0,0 +1,302 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_THREAD_GROUP_IMPL_H_ +#define _SOFA_PBRPC_THREAD_GROUP_IMPL_H_ + +#include +#include +#include + +#include +#include +#include + +namespace sofa { +namespace pbrpc { + +// Defined in this file. +class ThreadGroupImpl; +typedef sofa::pbrpc::shared_ptr ThreadGroupImplPtr; + +// Thread init and destroy function. Should be permanent closure. +typedef ExtClosure* ThreadInitFunc; +typedef ExtClosure* ThreadDestFunc; + +class ThreadGroupImpl +{ +public: + struct ThreadParam + { + int id; // sequence id in the thread group, starting from 0 + IOService* io_service; + ThreadInitFunc init_func; + ThreadDestFunc dest_func; + bool init_done; + bool init_fail; + + ThreadParam() : id(0), io_service(NULL), init_func(NULL), dest_func(NULL), + init_done(false), init_fail(false) {} + ~ThreadParam() {} + }; +public: + ThreadGroupImpl(int thread_num, const std::string& name = "") + : _is_running(false) + , _thread_num(std::max(thread_num, 1)) + , _name(name) + , _init_func(NULL) + , _dest_func(NULL) + , _io_service_work(NULL) + , _threads(NULL) + , _thread_params(NULL) + { + if (_name.empty()) + { + char tmp[20]; + sprintf(tmp, "%p", this); + _name = tmp; + } + } + + ~ThreadGroupImpl() + { + stop(); + } + + int thread_num() const + { + return _thread_num; + } + + std::string name() const + { + return _name; + } + + // The "init_func" and "dest_func" should be permanent closure, and + // owned by the caller. + void set_init_func(ThreadInitFunc init_func) + { + _init_func = init_func; + } + void set_dest_func(ThreadDestFunc dest_func) + { + _dest_func = dest_func; + } + + IOService& io_service() + { + return _io_service; + } + + bool start() + { + if (_is_running) return true; + _is_running = true; + +#if defined( LOG ) + LOG(INFO) << "start(): starting thread group [" << _name << "], thread_num=" << _thread_num; +#else + SLOG(INFO, "start(): starting thread group [%s], thread_num=%d", _name.c_str(), _thread_num); +#endif + _io_service_work = new IOServiceWork(_io_service); + _threads = new pthread_t[_thread_num]; + _thread_params = new ThreadParam[_thread_num]; + for (int i = 0; i < _thread_num; ++i) + { + _thread_params[i].id = i; + _thread_params[i].io_service = &_io_service; + _thread_params[i].init_func = _init_func; + _thread_params[i].dest_func = _dest_func; + int ret = pthread_create(&_threads[i], NULL, &ThreadGroupImpl::thread_run, &_thread_params[i]); + if (ret != 0) + { +#if defined( LOG ) + LOG(ERROR) << "start(): create thread[" << i << "] failed: error=%d" << ret; +#else + SLOG(ERROR, "start(): create thread[%d] failed: error=%d", i, ret); +#endif + _thread_num = i; + stop(); + return false; + } + } + // wait for init done + bool init_fail = false; + while (true) + { + int done_num = 0; + for (int i = 0; i < _thread_num; ++i) + { + if (_thread_params[i].init_done) + { + if (_thread_params[i].init_fail) + { + init_fail = true; + break; + } + else + { + ++done_num; + } + } + } + if (init_fail || done_num == _thread_num) + { + break; + } + usleep(100000); + } + if (init_fail) + { +#if defined( LOG ) + LOG(ERROR) << "start(): start thread group [" << _name << "] failed"; +#else + SLOG(ERROR, "start(): start thread group [%s] failed", _name.c_str()); +#endif + stop(); + return false; + } +#if defined( LOG ) + LOG(INFO) << "start(): thread group [" << _name << "] started, thread_num=" << _thread_num; +#else + SLOG(INFO, "start(): thread group [%s] started, thread_num=%d", _name.c_str(), _thread_num); +#endif + return true; + } + + void stop() + { + if (!_is_running) return; + _is_running = false; + + delete _io_service_work; + _io_service_work = NULL; + + for (int i = 0; i < _thread_num; ++i) + { + int ret = pthread_join(_threads[i], NULL); + if (ret != 0) + { +#if defined( LOG ) + LOG(ERROR) << "stop(): join thread[" << i << "] failed: error=%d" << ret; +#else + SLOG(ERROR, "stop(): join thread[%d] failed: error=%d", i, ret); +#endif + } + } + + delete []_thread_params; + _thread_params = NULL; + delete []_threads; + _threads = NULL; + +#if defined( LOG ) + LOG(INFO) << "stop(): thread group [" << _name << "] stopped"; +#else + SLOG(INFO, "stop(): thread group [%s] stopped", _name.c_str()); +#endif + } + + // Request the thread group to invoke the given handler. + // The handler may be executed inside this function if the guarantee can be met. + // The function signature of the handler must be: + // void handler(); + template< typename CompletionHandler > + void dispatch(CompletionHandler handler) + { + _io_service.dispatch(handler); + } + + // Request the thread group to invoke the given handler and return immediately. + // It guarantees that the handle will not be called from inside this function. + // The function signature of the handler must be: + // void handler(); + template< typename CompletionHandler > + void post(CompletionHandler handler) + { + _io_service.post(handler); + } + + void dispatch(google::protobuf::Closure* handle) + { + dispatch(boost::bind(&ThreadGroupImpl::closure_run_helper, handle)); + } + + void post(google::protobuf::Closure* handle) + { + post(boost::bind(&closure_run_helper, handle)); + } + + void dispatch(ExtClosure* handle) + { + dispatch(boost::bind(&ThreadGroupImpl::ext_closure_run_helper, handle)); + } + + void post(ExtClosure* handle) + { + post(boost::bind(&ext_closure_run_helper, handle)); + } + +private: + static void* thread_run(void* param) + { + ThreadParam* thread_param = reinterpret_cast(param); + // init + if (thread_param->init_func && !thread_param->init_func->Run()) + { +#if defined( LOG ) + LOG(ERROR) << "thread_run(): init thread [" << thread_param->id << "] failed"; +#else + SLOG(ERROR, "thread_run(): init thread [%d] failed", thread_param->id); +#endif + thread_param->init_fail = true; + } + thread_param->init_done = true; + // run asio + if (!thread_param->init_fail) + { + thread_param->io_service->run(); + } + // destroy + if (thread_param->dest_func) + { + thread_param->dest_func->Run(); + } + return NULL; + } + + static void closure_run_helper(google::protobuf::Closure* handle) + { + handle->Run(); + } + + static void ext_closure_run_helper(ExtClosure* handle) + { + handle->Run(); + } + +private: + volatile bool _is_running; + int _thread_num; + std::string _name; + ThreadInitFunc _init_func; + ThreadDestFunc _dest_func; + + IOService _io_service; + IOServiceWork* _io_service_work; + pthread_t* _threads; + ThreadParam* _thread_params; + + SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(ThreadGroupImpl); +}; + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_THREAD_GROUP_IMPL_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/timeout_manager.cc b/src/sofa/pbrpc/timeout_manager.cc new file mode 100644 index 0000000..deab277 --- /dev/null +++ b/src/sofa/pbrpc/timeout_manager.cc @@ -0,0 +1,48 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include +#include + +namespace sofa { +namespace pbrpc { + +TimeoutManager::TimeoutManager() +{ + _imp.reset(new TimeoutManagerImpl()); + _imp->start(); +} + +TimeoutManager::~TimeoutManager() +{ + _imp->stop(); + _imp.reset(); +} + +void TimeoutManager::clear() +{ + _imp->clear(); +} + +TimeoutManager::Id TimeoutManager::add(int64 interval, Callback* callback) +{ + return _imp->add(interval, callback); +} + +TimeoutManager::Id TimeoutManager::add_repeating(int64 interval, Callback* callback) +{ + return _imp->add_repeating(interval, callback); +} + +bool TimeoutManager::erase(Id id) +{ + return _imp->erase(id); +} + +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/timeout_manager.h b/src/sofa/pbrpc/timeout_manager.h new file mode 100644 index 0000000..da765ac --- /dev/null +++ b/src/sofa/pbrpc/timeout_manager.h @@ -0,0 +1,103 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_TIMEOUT_MANAGER_H_ +#define _SOFA_PBRPC_TIMEOUT_MANAGER_H_ + +#include +#include + +namespace sofa { +namespace pbrpc { + +// Defined in this file. +class TimeoutManager; +typedef sofa::pbrpc::shared_ptr TimeoutManagerPtr; + +// Defined in other files. +class TimeoutManagerImpl; + +class TimeoutManager +{ +public: + // Timeout id. Every timeout event will be assigned an unique id. + typedef uint64 Id; + + // Timeout type. Used in callback. + // - TIMEOUTED : callback triggered when timeout. + // - ERASED : callback triggered when do 'erase()'. + // - CLEARED : callback triggered when do 'clear()' or destructor. + enum Type { + TIMEOUTED = 0, + ERASED = 1, + CLEARED = 2 + }; + + // Callback. The callback should be a light weight routine, which means you + // should not do numerous things or block it. + typedef ExtClosure Callback; + + // Contructor. + TimeoutManager(); + + // Destructor. It will invoke clear() to clear all timeout events. + ~TimeoutManager(); + + // Clear all timeout events from the manager. All associated callbacks will + // be invoked with type = CLEARED, + void clear(); + + // Add a one-time timeout event that will be triggered once after time of + // "interval" milli-seconds from now. + // + // The "interval" should be no less than 0. + // + // The "callback" should be a self delete closure which can be created through + // NewExtClosure(). + // + // The "callback" will always be invoked only once, in following cases: + // - Timeouted, with type = TIMEOUTED. + // - Erased, with type = ERASED. + // - Cleared, with type = CLEARED. + // + // After callback done, the "callback" closure will be self deleted. + Id add(int64 interval, Callback* callback); + + // Add a repeating timeout event that will be triggered after each "interval" + // milli-seconds. + // + // The "interval" should be no less than 0. + // + // The "callback" should be a permanent closure which can be created through + // NewPermanentExtClosure(). + // + // The "callback" will always be invoked, in following cases: + // - Timeouted, with type = TIMEOUTED, maybe invoked for multi-times. + // - Erased, with type = ERASED. + // - Cleared, with type = CLEARED. + // + // If callbacked in case of ERASED or CLEARED, the "callback" closure will + // deleted by the manager. + Id add_repeating(int64 interval, Callback* callback); + + // Erase a given timeout event, returns true if the event was actually erased + // and false if it didn't exist. + // + // If returns true, the associated callback will be invoked with type = ERASED. + bool erase(Id id); + +private: + sofa::pbrpc::shared_ptr _imp; + + SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(TimeoutManager); +}; + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_TIMEOUT_MANAGER_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/timeout_manager_impl.cc b/src/sofa/pbrpc/timeout_manager_impl.cc new file mode 100644 index 0000000..c10c506 --- /dev/null +++ b/src/sofa/pbrpc/timeout_manager_impl.cc @@ -0,0 +1,161 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include + +namespace sofa { +namespace pbrpc { + +TimeoutManagerImpl::TimeoutManagerImpl() + : _is_running(false) + , _epoch_time(ptime_now()) + , _last_ticks(0) + , _rectify_ticks(time_duration_milliseconds(kTimerGranularity).ticks()) + , _next_id(1) +{ +} + +TimeoutManagerImpl::~TimeoutManagerImpl() +{ + stop(); +} + +bool TimeoutManagerImpl::is_running() +{ + return _is_running; +} + +void TimeoutManagerImpl::start() +{ + ScopedLocker _(_start_stop_lock); + if (_is_running) + return; + _is_running = true; + + _thread_group.reset(new ThreadGroupImpl(kThreadCount)); + _thread_group->start(); + + _timer_worker.reset(new TimerWorker(_thread_group->io_service())); + _timer_worker->set_time_duration(time_duration_milliseconds(kTimerGranularity)); + _timer_worker->set_work_routine(boost::bind( + &TimeoutManagerImpl::timer_run, shared_from_this(), _1)); + _timer_worker->start(); +} + +void TimeoutManagerImpl::stop() +{ + ScopedLocker _(_start_stop_lock); + if (!_is_running) return; + _is_running = false; + + _timer_worker->stop(); + _thread_group->stop(); + + clear(); + + _timer_worker.reset(); + _thread_group.reset(); +} + +void TimeoutManagerImpl::clear() +{ + EventVec cleared; + { + ScopedLocker _(_timeouts_lock); + if (!_timeouts.empty()) { + IdIndex& by_id = _timeouts.get(); + cleared.insert(cleared.end(), by_id.begin(), by_id.end()); + _timeouts.clear(); + } + } + for (EventVec::iterator it = cleared.begin(); it != cleared.end(); ++it) { + Callback* callback = it->callback; + bool should_delete = !callback->IsSelfDelete(); + callback->Run(it->id, TimeoutManager::CLEARED); + if (should_delete) delete callback; + } +} + +TimeoutManagerImpl::Id TimeoutManagerImpl::add(int64 interval, Callback* callback) +{ + SCHECK_GE(interval, 0); + SCHECK(callback->IsSelfDelete()); + ScopedLocker _(_timeouts_lock); + Id id = _next_id++; + _timeouts.insert(Event(id, calc_expiration(interval), -1, callback)); + return id; +} + +TimeoutManagerImpl::Id TimeoutManagerImpl::add_repeating(int64 interval, Callback* callback) +{ + SCHECK_GE(interval, 0); + SCHECK(!callback->IsSelfDelete()); + ScopedLocker _(_timeouts_lock); + Id id = _next_id++; + _timeouts.insert(Event(id, calc_expiration(interval), interval, callback)); + return id; +} + +bool TimeoutManagerImpl::erase(Id id) +{ + Callback* callback = NULL; + { + ScopedLocker _(_timeouts_lock); + IdIndex& by_id = _timeouts.get(); + IdIndex::iterator find = by_id.find(id); + if (find == by_id.end()) return false; + callback = find->callback; + by_id.erase(find); + } + bool should_delete = !callback->IsSelfDelete(); + callback->Run(id, TimeoutManager::ERASED); + if (should_delete) delete callback; + return true; +} + +void TimeoutManagerImpl::timer_run(const PTime& now) +{ + if (!_is_running) return; + int64 now_ticks = (now - _epoch_time).ticks(); + _last_ticks = now_ticks; + + EventVec expired; + { + ScopedLocker _(_timeouts_lock); + if (!_timeouts.empty()) { + ExpirationIndex& by_expiration = _timeouts.get(); + ExpirationIndex::iterator exp_end = by_expiration.upper_bound(now_ticks); + expired.insert(expired.end(), by_expiration.begin(), exp_end); + by_expiration.erase(by_expiration.begin(), exp_end); + } + } + + if (expired.empty()) return; + + // Reinsert if repeating, do this before executing callbacks + // so the callbacks have a chance to call erase + EventVec repeated; + for (EventVec::iterator it = expired.begin(); it != expired.end(); ++it) { + if (it->repeat_interval >= 0) { + repeated.push_back(Event(it->id, calc_expiration(it->repeat_interval), + it->repeat_interval, it->callback)); + } + } + if (!repeated.empty()) { + ScopedLocker _(_timeouts_lock); + _timeouts.insert(repeated.begin(), repeated.end()); + } + + // Execute callbacks + for (EventVec::iterator it = expired.begin(); it != expired.end(); ++it) { + it->callback->Run(it->id, TimeoutManager::TIMEOUTED); + } +} + +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/timeout_manager_impl.h b/src/sofa/pbrpc/timeout_manager_impl.h new file mode 100644 index 0000000..eec0411 --- /dev/null +++ b/src/sofa/pbrpc/timeout_manager_impl.h @@ -0,0 +1,116 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_TIMEOUT_MANAGER_IMPL_H_ +#define _SOFA_PBRPC_TIMEOUT_MANAGER_IMPL_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sofa { +namespace pbrpc { + +// Defined in this file. +class TimeoutManagerImpl; +typedef sofa::pbrpc::shared_ptr TimeoutManagerImplPtr; + +class TimeoutManagerImpl : public sofa::pbrpc::enable_shared_from_this +{ +public: + // Thread number for timer and callbacks. + const static int kThreadCount = 1; + // Timeout granularity of timer in milli-seconds. + const static int64 kTimerGranularity = 10; + + typedef TimeoutManager::Id Id; + typedef TimeoutManager::Type Type; + typedef TimeoutManager::Callback Callback; + + TimeoutManagerImpl(); + ~TimeoutManagerImpl(); + + bool is_running(); + + void start(); + + void stop(); + + void clear(); + + Id add(int64 interval, Callback* callback); + + Id add_repeating(int64 interval, Callback* callback); + + bool erase(Id id); + +private: + // Given interval in milli-seconds, calculate expiration ticks. + inline int64 calc_expiration(int64 interval) + { + return _last_ticks + time_duration_milliseconds(interval).ticks() + _rectify_ticks; + } + + void timer_run(const PTime& now); + +private: + struct Event { + Id id; + int64 expiration; + int64 repeat_interval; + Callback* callback; + Event(Id i, int64 e, int64 r, Callback* c) + : id(i), expiration(e), repeat_interval(r), callback(c) {} + }; + + typedef boost::multi_index_container< + Event, + boost::multi_index::indexed_by< + boost::multi_index::ordered_unique >, + boost::multi_index::ordered_non_unique > + > + > Set; + + enum { + BY_ID=0, + BY_EXPIRATION=1 + }; + + typedef Set::nth_index::type IdIndex; + typedef Set::nth_index::type ExpirationIndex; + typedef std::vector EventVec; + + volatile bool _is_running; + MutexLock _start_stop_lock; + PTime _epoch_time; + volatile int64 _last_ticks; + int64 _rectify_ticks; + + ThreadGroupImplPtr _thread_group; + TimerWorkerPtr _timer_worker; + + Set _timeouts; + Id _next_id; + MutexLock _timeouts_lock; +}; + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_TIMEOUT_MANAGER_IMPL_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/timeout_queue.cc b/src/sofa/pbrpc/timeout_queue.cc new file mode 100644 index 0000000..31d6a6a --- /dev/null +++ b/src/sofa/pbrpc/timeout_queue.cc @@ -0,0 +1,89 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include + +#include + +namespace sofa { +namespace pbrpc { + +TimeoutQueue::~TimeoutQueue() +{ +} + +uint64 TimeoutQueue::add( + int64 now, + int64 delay, + Callback* callback) +{ + SCHECK(callback->IsSelfDelete()); + uint64 id = _next_id++; + _timeouts.insert(Event(id, now + delay, -1, callback)); + return id; +} + +uint64 TimeoutQueue::add_repeating( + int64 now, + int64 interval, + Callback* callback) +{ + SCHECK(!callback->IsSelfDelete()); + uint64 id = _next_id++; + _timeouts.insert(Event(id, now + interval, interval, callback)); + return id; +} + +int64 TimeoutQueue::next_expiration() const +{ + return (_timeouts.empty() ? kint64max : + _timeouts.get().begin()->expiration); +} + +bool TimeoutQueue::erase(uint64 id) +{ + IdIndex& by_id = _timeouts.get(); + IdIndex::iterator find = by_id.find(id); + if (find == by_id.end()) return false; + delete find->callback; + by_id.erase(find); + return true; +} + +int64 TimeoutQueue::run_internal(int64 now, bool once_only) +{ + ExpirationIndex& by_expiration = _timeouts.get(); + int64 next_exp; + do { + ExpirationIndex::iterator exp_end = by_expiration.upper_bound(now); + std::vector expired(by_expiration.begin(), exp_end); + by_expiration.erase(by_expiration.begin(), exp_end); + for (std::vector::iterator it = expired.begin(); + it != expired.end(); ++it) { + Event& event = *it; + // Reinsert if repeating, do this before executing callbacks + // so the callbacks have a chance to call erase + if (event.repeat_interval >= 0) { + _timeouts.insert(Event(event.id, now + event.repeat_interval, + event.repeat_interval, event.callback)); + } + } + + // Call callbacks + for (std::vector::iterator it = expired.begin(); + it != expired.end(); ++it) { + Event& event = *it; + event.callback->Run(event.id, now); + } + next_exp = next_expiration(); + } while (!once_only && next_exp <= now); + return next_exp; +} + +} // namespace pbrpc +} // namespace sofa + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/timeout_queue.h b/src/sofa/pbrpc/timeout_queue.h new file mode 100644 index 0000000..0b4e455 --- /dev/null +++ b/src/sofa/pbrpc/timeout_queue.h @@ -0,0 +1,128 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_TIMEOUT_QUEUE_H_ +#define _SOFA_PBRPC_TIMEOUT_QUEUE_H_ + +#include +#include +#include +#include +#include +#include + +namespace sofa { +namespace pbrpc { + +// Callback. + +class TimeoutQueue { +public: + typedef ExtClosure Callback; + + TimeoutQueue() : _next_id(1) { } + ~TimeoutQueue(); + + /** + * Add a one-time timeout event that will fire "delay" time units from "now" + * (that is, the first time that run*() is called with a time value >= now + * + delay). + * + * The "callback" should be a self delete closure (created by + * NewExtClosure()). + */ + uint64 add(int64 now, int64 delay, Callback* callback); + + /** + * Add a repeating timeout event that will fire every "interval" time units + * (it will first fire when run*() is called with a time value >= + * now + interval). + * + * run*() will always invoke each repeating event at most once, even if + * more than one "interval" period has passed. + * + * The "callback" should be a permanent closure (created by + * NewPermanentExtClosure()). + */ + uint64 add_repeating(int64 now, int64 interval, Callback* callback); + + /** + * Erase a given timeout event, returns true if the event was actually + * erased and false if it didn't exist in our queue. + */ + bool erase(uint64 id); + + /** + * Process all events that are due at times <= "now" by calling their + * callbacks. + * + * Callbacks are allowed to call back into the queue and add / erase events; + * they might create more events that are already due. In this case, + * run_once() will only go through the queue once, and return a "next + * expiration" time in the past or present (<= now); run_loop() + * will process the queue again, until there are no events already due. + * + * Note that it is then possible for runLoop to never return if + * callbacks re-add themselves to the queue (or if you have repeating + * callbacks with an interval of 0). + * + * Return the time that the next event will be due (same as + * next_expiration(), below) + */ + int64 run_once(int64 now) { return run_internal(now, true); } + int64 run_loop(int64 now) { return run_internal(now, false); } + + /** + * Return the time that the next event will be due. + */ + int64 next_expiration() const; + +private: + // noncopyable + TimeoutQueue(const TimeoutQueue&); + TimeoutQueue& operator=(const TimeoutQueue&); + + int64 run_internal(int64 now, bool run_once); + + struct Event { + uint64 id; + int64 expiration; + int64 repeat_interval; + Callback* callback; + Event(uint64 i, int64 e, int64 r, Callback* c) + : id(i), expiration(e), repeat_interval(r), callback(c) {} + }; + + typedef boost::multi_index_container< + Event, + boost::multi_index::indexed_by< + boost::multi_index::ordered_unique >, + boost::multi_index::ordered_non_unique > + > + > Set; + + enum { + BY_ID=0, + BY_EXPIRATION=1 + }; + + typedef Set::nth_index::type ExpirationIndex; + typedef Set::nth_index::type IdIndex; + + Set _timeouts; + uint64 _next_id; +}; + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_TIMEOUT_QUEUE_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/timer_worker.h b/src/sofa/pbrpc/timer_worker.h new file mode 100644 index 0000000..7bba2dd --- /dev/null +++ b/src/sofa/pbrpc/timer_worker.h @@ -0,0 +1,109 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_TIMER_WORKER_H_ +#define _SOFA_PBRPC_TIMER_WORKER_H_ + +#include + +namespace sofa { +namespace pbrpc { + +class TimerWorker : public sofa::pbrpc::enable_shared_from_this +{ +public: + typedef boost::function WorkRoutine; + +public: + TimerWorker(IOService& io_service) + : _io_service(io_service) + , _is_running(false) + , _time_duration(time_duration_seconds(1)) + , _work_routine(NULL) + , _timer(io_service) + , _strand(io_service) + {} + + ~TimerWorker() + { + SOFA_PBRPC_FUNCTION_TRACE; + stop(); + } + + bool is_running() + { + return _is_running; + } + + void set_time_duration(const TimeDuration& time_duration) + { + _time_duration = time_duration; + } + + void set_work_routine(const WorkRoutine& work_routine) + { + _work_routine = work_routine; + } + + void start() + { + if (_is_running) return; + _is_running = true; + + ScopedLocker _(_timer_lock); + _timer.expires_from_now(_time_duration); + _timer.async_wait(_strand.wrap(boost::bind( + &TimerWorker::on_timeout, shared_from_this(), _1))); + } + + void stop() + { + if (!_is_running) return; + _is_running = false; + + ScopedLocker _(_timer_lock); + _timer.cancel(); + } + +private: + void on_timeout(const boost::system::error_code& ec) + { + if (_is_running) + { + PTime now = ptime_now(); + + if (ec != boost::asio::error::operation_aborted && _work_routine) + { + _work_routine(now); + } + + ScopedLocker _(_timer_lock); + _timer.expires_at(now + _time_duration); + _timer.async_wait(_strand.wrap(boost::bind( + &TimerWorker::on_timeout, shared_from_this(), _1))); + } + } + +private: + IOService& _io_service; + volatile bool _is_running; + + TimeDuration _time_duration; + WorkRoutine _work_routine; + + IOServiceTimer _timer; + MutexLock _timer_lock; + IOServiceStrand _strand; + + SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(TimerWorker); +}; // class TimerWorker + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_TIMER_WORKER_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/tran_buf_pool.h b/src/sofa/pbrpc/tran_buf_pool.h new file mode 100644 index 0000000..818be43 --- /dev/null +++ b/src/sofa/pbrpc/tran_buf_pool.h @@ -0,0 +1,75 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_TRAN_BUF_POOL_H_ +#define _SOFA_PBRPC_TRAN_BUF_POOL_H_ + +#include + +#ifndef SOFA_PBRPC_TRAN_BUF_BLOCK_SIZE +#define SOFA_PBRPC_TRAN_BUF_BLOCK_SIZE (1024u - sizeof(RefCountType)) +#endif + +namespace sofa { +namespace pbrpc { + +// Reference counted tran buf pool. +// Thread safe. +class TranBufPool +{ +public: + typedef int RefCountType; + + // Get the size of single block. + inline static int block_size() + { + return static_cast(SOFA_PBRPC_TRAN_BUF_BLOCK_SIZE); + } + + // Allocate a block. Return NULL if failed. + // + // Postconditions: + // * If succeed, the reference count of the block is equal to 1. + inline static void * malloc() + { + void * p = ::malloc(SOFA_PBRPC_TRAN_BUF_BLOCK_SIZE + sizeof(RefCountType)); + if (p != NULL) + { + *(reinterpret_cast(p)) = 1; + p = reinterpret_cast(p) + 1; + } + return p; + } + + // Increase the reference count of the block. + // + // Preconditions: + // * The block pointed by "p" was allocated by this pool and is in use currently. + inline static void add_ref(void * p) + { + sofa::pbrpc::atomic_inc(reinterpret_cast(p) - 1); + } + + // Decrease the reference count of the block. If the reference count equals + // to 0 afterward, then put the block back to the free list + // + // Preconditions: + // * The block pointed by "p" was allocated by this pool and is in use currently. + inline static void free(void * p) + { + if (sofa::pbrpc::atomic_dec_ret_old(reinterpret_cast(p) - 1) == 1) + { + ::free(reinterpret_cast(p) - 1); + } + } +}; // class TranBufPool + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_TRAN_BUF_POOL_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/src/sofa/pbrpc/wait_event.h b/src/sofa/pbrpc/wait_event.h new file mode 100644 index 0000000..e3a7abb --- /dev/null +++ b/src/sofa/pbrpc/wait_event.h @@ -0,0 +1,59 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#ifndef _SOFA_PBRPC_WAIT_EVENT_H_ +#define _SOFA_PBRPC_WAIT_EVENT_H_ + +#include + +namespace sofa { +namespace pbrpc { + +class WaitEvent +{ +public: + WaitEvent() : _signaled(false) + { + pthread_mutex_init(&_lock, NULL); + pthread_cond_init(&_cond, NULL); + } + ~WaitEvent() + { + pthread_mutex_destroy(&_lock); + pthread_cond_destroy(&_cond); + } + + void Wait() + { + pthread_mutex_lock(&_lock); + while (!_signaled) + { + pthread_cond_wait(&_cond, &_lock); + } + _signaled = false; + pthread_mutex_unlock(&_lock); + } + + void Signal() + { + pthread_mutex_lock(&_lock); + _signaled = true; + pthread_cond_signal(&_cond); + pthread_mutex_unlock(&_lock); + } + +private: + pthread_mutex_t _lock; + pthread_cond_t _cond; + bool _signaled; +}; + +} // namespace pbrpc +} // namespace sofa + +#endif // _SOFA_PBRPC_WAIT_EVENT_H_ + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/unit-test/Makefile b/unit-test/Makefile new file mode 100644 index 0000000..0f56126 --- /dev/null +++ b/unit-test/Makefile @@ -0,0 +1,106 @@ +# Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. See the AUTHORS file for names of contributors. + +#----------------------------------------------- +# Uncomment exactly one of the lines labelled (A), (B), and (C) below +# to switch between compilation modes. +# +# OPT ?= -O2 # (A) Production use (optimized mode) +OPT ?= -g2 # (B) Debug mode, w/ full line-level debugging symbols +# OPT ?= -O2 -g2 # (C) Profiling mode: opt, but w/debugging symbols +#----------------------------------------------- + +#----------------------------------------------- +# !!! Do not change the following lines !!! +#----------------------------------------------- + +include ../depends.mk +include depends.mk + +CXX=g++ +INCPATH=-I. -I../src -I$(BOOST_HEADER_DIR) -I$(PROTOBUF_DIR)/include \ + -I$(SNAPPY_DIR)/include -I$(ZLIB_DIR)/include -I$(GTEST_DIR)/include +CXXFLAGS += $(OPT) -pipe -W -Wall -fPIC -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -Dprivate=public $(INCPATH) + +LIBRARY=../libsofa-pbrpc.a $(PROTOBUF_DIR)/lib/libprotobuf.a $(SNAPPY_DIR)/lib/libsnappy.a +LDFLAGS += -L$(ZLIB_DIR)/lib -lpthread -lrt -lz + +PROTO_SRC=test_data.proto +PROTO_OBJ=$(patsubst %.proto,%.pb.o,$(PROTO_SRC)) +PROTO_OPTIONS=--proto_path=. --proto_path=../src --proto_path=$(PROTOBUF_DIR)/include + +TESTS = \ + test_common \ + test_atomic \ + test_epoll_support \ + test_tran_buf_pool \ + test_buffer \ + test_closure \ + test_ext_closure \ + test_thread_group \ + test_timeout_queue \ + test_timeout_manager + +all: check_depends $(TESTS) + +.PHONY: check_depends clean + +check_depends: + @if [ ! -f "$(BOOST_HEADER_DIR)/boost/smart_ptr.hpp" ]; then echo "ERROR: need boost header"; exit 1; fi + @if [ ! -f "$(PROTOBUF_DIR)/include/google/protobuf/message.h" ]; then echo "ERROR: need protobuf header"; exit 1; fi + @if [ ! -f "$(PROTOBUF_DIR)/lib/libprotobuf.a" ]; then echo "ERROR: need protobuf lib"; exit 1; fi + @if [ ! -f "$(PROTOBUF_DIR)/bin/protoc" ]; then echo "ERROR: need protoc binary"; exit 1; fi + @if [ ! -f "$(SNAPPY_DIR)/include/snappy.h" ]; then echo "ERROR: need snappy header"; exit 1; fi + @if [ ! -f "$(SNAPPY_DIR)/lib/libsnappy.a" ]; then echo "ERROR: need snappy lib"; exit 1; fi + @if [ ! -f "$(GTEST_DIR)/src/gtest-all.cc" ]; then echo "ERROR: need gtest"; exit 1; fi + @if [ ! -f "../libsofa-pbrpc.a" ]; then echo "ERROR: should build sofa-pbrpc first"; exit 1; fi + +clean: + @rm -f $(TESTS) *.o *.pb.* libgtest.a + +rebuild: clean all + +test_common: test_common.o libgtest.a + $(CXX) $(LDFLAGS) $^ -o $@ $(LIBRARY) + +test_atomic: test_atomic.o libgtest.a + $(CXX) $(LDFLAGS) $^ -o $@ $(LIBRARY) + +test_epoll_support: test_epoll_support.o libgtest.a + $(CXX) $(LDFLAGS) $^ -o $@ $(LIBRARY) + +test_tran_buf_pool: test_tran_buf_pool.o libgtest.a + $(CXX) $(LDFLAGS) $^ -o $@ $(LIBRARY) + +test_buffer: test_buffer.o test_data.pb.o libgtest.a + $(CXX) $(LDFLAGS) $^ -o $@ $(LIBRARY) + +test_closure: test_closure.o libgtest.a + $(CXX) $(LDFLAGS) $^ -o $@ $(LIBRARY) + +test_ext_closure: test_ext_closure.o libgtest.a + $(CXX) $(LDFLAGS) $^ -o $@ $(LIBRARY) + +test_thread_group: test_thread_group.o libgtest.a + $(CXX) $(LDFLAGS) $^ -o $@ $(LIBRARY) + +test_timeout_queue: test_timeout_queue.o libgtest.a + $(CXX) $(LDFLAGS) $^ -o $@ $(LIBRARY) + +test_timeout_manager: test_timeout_manager.o libgtest.a + $(CXX) $(LDFLAGS) $^ -o $@ $(LIBRARY) + +%.pb.o: %.pb.cc + $(CXX) $(CXXFLAGS) -c $< -o $@ + +%.pb.cc: %.proto + $(PROTOBUF_DIR)/bin/protoc $(PROTO_OPTIONS) --cpp_out=. $< + +%.o: %.cc $(PROTO_OBJ) + $(CXX) $(CXXFLAGS) -c $< -o $@ + +libgtest.a: + g++ -isystem $(GTEST_DIR)/include -I$(GTEST_DIR) -pthread -c $(GTEST_DIR)/src/gtest-all.cc + ar -rv libgtest.a gtest-all.o + diff --git a/unit-test/depends.mk b/unit-test/depends.mk new file mode 100644 index 0000000..ce597b9 --- /dev/null +++ b/unit-test/depends.mk @@ -0,0 +1,18 @@ +############################################################### +## Modified this file to specify your library path. +## +## Depending libs: +## gtest-1.7.0 +## +############################################################### + +############################################################### +## Google Test directory. +## +## Check file exist: +## $(GTEST_DIR)/src/gtest-all.cc +## +#GTEST_DIR=/home/users/qinzuoyan01/libs/gtest-1.7.0 +GTEST_DIR= +############################################################### + diff --git a/unit-test/run_test.sh b/unit-test/run_test.sh new file mode 100644 index 0000000..1b3c0ed --- /dev/null +++ b/unit-test/run_test.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +function run() +{ + echo "===========" $1 "===========" + ./$1 + if [ $? -ne 0 ]; then + echo "TEST FAILED!!!" + exit 1 + fi +} + +num=0 +for test_case in `find . -name 'test_*' -a -perm -100` +do + run $test_case + num=$((num+1)) +done + +echo +echo "CASE NUM: $num" +echo "ALL CASE PASSED!!!" + diff --git a/unit-test/test_atomic.cc b/unit-test/test_atomic.cc new file mode 100644 index 0000000..60fb1b7 --- /dev/null +++ b/unit-test/test_atomic.cc @@ -0,0 +1,49 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include +#include + +using namespace sofa::pbrpc; + +class AtomicTest: public ::testing::Test {}; + +TEST_F(AtomicTest, test) +{ + const int g = 1024 * 1024 * 1024; + int a = 10; + ASSERT_EQ(10, atomic_add_ret_old(&a, 5)); + ASSERT_EQ(15, a); + ASSERT_EQ(15, atomic_add_ret_old(&a, -10)); + ASSERT_EQ(5, a); + ASSERT_EQ(5, atomic_add_ret_old(&a, -5)); + ASSERT_EQ(0, a); + ASSERT_EQ(0, atomic_add_ret_old(&a, -5)); + ASSERT_EQ(-5, a); + ASSERT_EQ(-5, atomic_add_ret_old(&a, 5)); + ASSERT_EQ(0, a); + ASSERT_EQ(0, atomic_add_ret_old(&a, g)); + ASSERT_EQ(g, a); + ASSERT_EQ(g, atomic_add_ret_old(&a, -g * 2)); + ASSERT_EQ(-g, a); + + ASSERT_EQ(-g, atomic_swap(&a, 0)); + ASSERT_EQ(0, a); + + ASSERT_EQ(0, atomic_comp_swap(&a, 1, 1)); + ASSERT_EQ(0, a); + + ASSERT_EQ(0, atomic_comp_swap(&a, 1, 0)); + ASSERT_EQ(1, a); +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/unit-test/test_buffer.cc b/unit-test/test_buffer.cc new file mode 100644 index 0000000..34c2593 --- /dev/null +++ b/unit-test/test_buffer.cc @@ -0,0 +1,521 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#define SOFA_PBRPC_TRAN_BUF_BLOCK_SIZE 32 + +#include +#include +#include +#include +#include + +#include +#include // ATTENTION: include source file for different block size +#include +#include +#include +#include "test_data.pb.h" + +using namespace sofa::pbrpc; + +static char* rand_str(char* str, size_t len) +{ + for (size_t i = 0; i < len; ++i) + str[i] = 'A'+ std::rand() % 26; + return str; +} + +class ReadBufferTest : public ::testing::Test +{ +public: + ReadBufferTest() {} + virtual ~ReadBufferTest() {} + virtual void SetUp() { + _block_size = TranBufPool::block_size(); + _block = static_cast(TranBufPool::malloc()); + ASSERT_TRUE(_block != NULL); + rand_str(_block, _block_size); + } + virtual void TearDown() { + TranBufPool::free(_block); + } + + int _block_size; + char* _block; +}; + +TEST_F(ReadBufferTest, Next) +{ + const void* data; + int size; + + // no block + { + ReadBufferPtr is(new ReadBuffer()); + ASSERT_EQ(0, is->TotalCount()); + ASSERT_EQ(0, is->ByteCount()); + ASSERT_FALSE(is->Next(&data, &size)); + ASSERT_EQ(0, is->_last_bytes); + } + + // one block + { + ReadBufferPtr is(new ReadBuffer()); + is->Append(BufHandle(_block, _block_size, 0)); + ASSERT_EQ(_block_size, is->TotalCount()); + + ASSERT_TRUE(is->Next(&data, &size)); + ASSERT_EQ(_block_size, size); + ASSERT_EQ(size, is->_last_bytes); + ASSERT_STREQ(_block, static_cast(data)); + ASSERT_EQ(size, is->ByteCount()); + + ASSERT_FALSE(is->Next(&data, &size)); + ASSERT_EQ(0, is->_last_bytes); + } + + // many blocks + { + std::vector blocks; + int gap = 2; // gap at head and tail + int buf_handle_size = _block_size - gap * 2; + + ReadBufferPtr is(new ReadBuffer()); + int rb_size = 0; + int block_count = 100; + for (int i = 0; i < block_count; ++i) + { + char* block = static_cast(TranBufPool::malloc()); + ASSERT_TRUE(block != NULL); + rand_str(block, _block_size); + blocks.push_back(block); + is->Append(BufHandle(block, buf_handle_size, gap)); + rb_size += buf_handle_size; + } + ASSERT_EQ(rb_size, is->TotalCount()); + + const void* data; + int size; + int count = is->TotalCount(); + int j = 0; + while (count > 0) + { + ASSERT_TRUE(is->Next(&data, &size)); + ASSERT_EQ(buf_handle_size, size); + ASSERT_EQ(size, is->_last_bytes); + ASSERT_EQ(0, strncmp(static_cast(data), blocks[j]+gap, buf_handle_size)); + count -= buf_handle_size; + ++j; + } + ASSERT_FALSE(is->Next(&data, &size)); + ASSERT_EQ(0, is->_last_bytes); + + for (int i = 0; i < block_count; ++i) + { + TranBufPool::free(blocks[i]); + } + } +} + +TEST_F(ReadBufferTest, BackUp) +{ + const void* data; + int size; + + // backup 0 + { + ReadBufferPtr is(new ReadBuffer()); + is->Append(BufHandle(_block, _block_size, 0)); + is->Append(BufHandle(_block, _block_size, 0)); + ASSERT_EQ(_block_size * 2, is->TotalCount()); + + ASSERT_TRUE(is->Next(&data, &size)); + ASSERT_EQ(_block_size, size); + ASSERT_EQ(_block_size, is->ByteCount()); + + is->BackUp(0); + ASSERT_EQ(0, is->_last_bytes); + ASSERT_EQ(_block_size, is->ByteCount()); + + ASSERT_TRUE(is->Next(&data, &size)); + ASSERT_EQ(_block_size, size); + ASSERT_EQ(_block_size * 2, is->ByteCount()); + + ASSERT_FALSE(is->Next(&data, &size)); + } + + // backup part + { + ReadBufferPtr is(new ReadBuffer()); + is->Append(BufHandle(_block, _block_size, 0)); + ASSERT_EQ(_block_size, is->TotalCount()); + + ASSERT_TRUE(is->Next(&data, &size)); + ASSERT_EQ(_block_size, size); + ASSERT_EQ(_block_size, is->ByteCount()); + + int count = _block_size / 2 + 1; + is->BackUp(count); + ASSERT_EQ(0, is->_last_bytes); + ASSERT_EQ(_block_size - count, is->ByteCount()); + + ASSERT_TRUE(is->Next(&data, &size)); + ASSERT_EQ(count, size); + ASSERT_EQ(_block_size, is->ByteCount()); + + ASSERT_FALSE(is->Next(&data, &size)); + } + + // backup all + { + ReadBufferPtr is(new ReadBuffer()); + is->Append(BufHandle(_block, _block_size, 0)); + ASSERT_EQ(_block_size, is->TotalCount()); + + ASSERT_TRUE(is->Next(&data, &size)); + ASSERT_EQ(_block_size, size); + ASSERT_EQ(_block_size, is->ByteCount()); + + is->BackUp(_block_size); + ASSERT_EQ(0, is->_last_bytes); + ASSERT_EQ(0, is->ByteCount()); + + ASSERT_TRUE(is->Next(&data, &size)); + ASSERT_EQ(_block_size, size); + ASSERT_EQ(_block_size, is->ByteCount()); + + ASSERT_FALSE(is->Next(&data, &size)); + } +} + +TEST_F(ReadBufferTest, Skip) +{ + const void* data; + int size; + + // skip 0 + { + ReadBufferPtr is(new ReadBuffer()); + is->Append(BufHandle(_block, _block_size, 0)); + ASSERT_EQ(_block_size, is->TotalCount()); + + ASSERT_TRUE(is->Skip(0)); + ASSERT_EQ(0, is->_last_bytes); + ASSERT_EQ(0, is->ByteCount()); + ASSERT_EQ(0, is->_last_bytes); + } + + // skip inside block + { + ReadBufferPtr is(new ReadBuffer()); + is->Append(BufHandle(_block, _block_size, 0)); + ASSERT_EQ(_block_size, is->TotalCount()); + + int count = _block_size / 2 + 1; + ASSERT_TRUE(is->Skip(count)); + ASSERT_EQ(0, is->_last_bytes); + ASSERT_EQ(count, is->ByteCount()); + + ASSERT_TRUE(is->Next(&data, &size)); + ASSERT_EQ(_block_size - count, size); + ASSERT_EQ(_block_size, is->ByteCount()); + + ASSERT_FALSE(is->Next(&data, &size)); + } + + // skip cross block + { + ReadBufferPtr is(new ReadBuffer()); + is->Append(BufHandle(_block, _block_size, 0)); + is->Append(BufHandle(_block, _block_size, 0)); + is->Append(BufHandle(_block, _block_size, 0)); + ASSERT_EQ(_block_size * 3, is->TotalCount()); + + int count = _block_size / 2 + 1; + ASSERT_TRUE(is->Skip(count)); + ASSERT_EQ(0, is->_last_bytes); + ASSERT_EQ(count, is->ByteCount()); + + ASSERT_TRUE(is->Skip(_block_size * 2)); + ASSERT_EQ(0, is->_last_bytes); + ASSERT_EQ(count + _block_size * 2, is->ByteCount()); + + ASSERT_TRUE(is->Next(&data, &size)); + ASSERT_EQ(_block_size - count, size); + ASSERT_EQ(_block_size * 3, is->ByteCount()); + + ASSERT_FALSE(is->Next(&data, &size)); + } + + // skip to the end + { + ReadBufferPtr is(new ReadBuffer()); + is->Append(BufHandle(_block, _block_size, 0)); + ASSERT_EQ(_block_size, is->TotalCount()); + + ASSERT_TRUE(is->Skip(_block_size)); + ASSERT_EQ(0, is->_last_bytes); + ASSERT_EQ(_block_size, is->ByteCount()); + + ASSERT_FALSE(is->Next(&data, &size)); + } + + // skip over end + { + ReadBufferPtr is(new ReadBuffer()); + is->Append(BufHandle(_block, _block_size, 0)); + ASSERT_EQ(_block_size, is->TotalCount()); + + ASSERT_FALSE(is->Skip(_block_size + 1)); + ASSERT_EQ(0, is->_last_bytes); + ASSERT_EQ(_block_size, is->ByteCount()); + + ASSERT_FALSE(is->Next(&data, &size)); + } +} + +class WriteBufferTest : public ::testing::Test +{ +public: + WriteBufferTest() {} + virtual ~WriteBufferTest() {} + virtual void SetUp() { + _block_size = TranBufPool::block_size(); + _block = static_cast(TranBufPool::malloc()); + ASSERT_TRUE(_block != NULL); + rand_str(_block, _block_size); + } + virtual void TearDown() { + TranBufPool::free(_block); + } + + int _block_size; + char* _block; +}; + +TEST_F(WriteBufferTest, Next) +{ + void* data; + int size; + + // no block + { + WriteBufferPtr os(new WriteBuffer()); + ASSERT_EQ(0, os->TotalCapacity()); + ASSERT_EQ(0, os->ByteCount()); + ASSERT_TRUE(os->_buf_list.empty()); + ASSERT_EQ(0, os->_last_bytes); + } + + // new block + { + WriteBufferPtr os(new WriteBuffer()); + + ASSERT_TRUE(os->Next(&data, &size)); + ASSERT_EQ(_block_size, size); + ASSERT_EQ(size, os->_last_bytes); + ASSERT_EQ(_block_size, os->TotalCapacity()); + ASSERT_EQ(_block_size, os->ByteCount()); + ASSERT_EQ(1u, os->_buf_list.size()); + ASSERT_EQ(_block_size, os->_last_bytes); + } +} + +TEST_F(WriteBufferTest, BackUp) +{ + void* data; + int size; + + // backup 0 + { + WriteBufferPtr os(new WriteBuffer()); + + ASSERT_TRUE(os->Next(&data, &size)); + ASSERT_EQ(_block_size, size); + ASSERT_EQ(size, os->_last_bytes); + ASSERT_EQ(_block_size, os->TotalCapacity()); + ASSERT_EQ(_block_size, os->ByteCount()); + ASSERT_EQ(1u, os->_buf_list.size()); + + os->BackUp(0); + ASSERT_EQ(0, os->_last_bytes); + ASSERT_EQ(_block_size, os->TotalCapacity()); + ASSERT_EQ(_block_size, os->ByteCount()); + ASSERT_EQ(1u, os->_buf_list.size()); + } + + // backup part + { + WriteBufferPtr os(new WriteBuffer()); + + ASSERT_TRUE(os->Next(&data, &size)); + + int count = _block_size / 2 + 1; + os->BackUp(count); + ASSERT_EQ(0, os->_last_bytes); + ASSERT_EQ(_block_size, os->TotalCapacity()); + ASSERT_EQ(_block_size - count, os->ByteCount()); + ASSERT_EQ(1u, os->_buf_list.size()); + + ASSERT_TRUE(os->Next(&data, &size)); + ASSERT_EQ(count, size); + ASSERT_EQ(size, os->_last_bytes); + ASSERT_EQ(_block_size, os->TotalCapacity()); + ASSERT_EQ(_block_size, os->ByteCount()); + ASSERT_EQ(1u, os->_buf_list.size()); + } + + // backup all + { + WriteBufferPtr os(new WriteBuffer()); + + ASSERT_TRUE(os->Next(&data, &size)); + + int count = _block_size; + os->BackUp(count); + ASSERT_EQ(0, os->_last_bytes); + ASSERT_EQ(_block_size, os->TotalCapacity()); + ASSERT_EQ(0, os->ByteCount()); + ASSERT_EQ(1u, os->_buf_list.size()); + + ASSERT_TRUE(os->Next(&data, &size)); + ASSERT_EQ(_block_size, size); + ASSERT_EQ(size, os->_last_bytes); + ASSERT_EQ(_block_size, os->TotalCapacity()); + ASSERT_EQ(_block_size, os->ByteCount()); + ASSERT_EQ(1u, os->_buf_list.size()); + } +} + +TEST_F(WriteBufferTest, Reserve) +{ + { + WriteBufferPtr os(new WriteBuffer()); + ASSERT_EQ(0, os->Reserve(10)); + ASSERT_EQ(10, os->ByteCount()); + ASSERT_EQ(1u, os->_buf_list.size()); + } + { + WriteBufferPtr os(new WriteBuffer()); + ASSERT_EQ(0, os->Reserve(40)); + ASSERT_EQ(40, os->ByteCount()); + ASSERT_EQ(2u, os->_buf_list.size()); + } + { + WriteBufferPtr os(new WriteBuffer()); + ASSERT_EQ(0, os->Reserve(10)); + ASSERT_EQ(10, os->Reserve(40)); + ASSERT_EQ(50, os->ByteCount()); + ASSERT_EQ(2u, os->_buf_list.size()); + } + { + WriteBufferPtr os(new WriteBuffer()); + ASSERT_EQ(0, os->Reserve(32)); + ASSERT_EQ(32, os->ByteCount()); + ASSERT_EQ(32, os->Reserve(32)); + ASSERT_EQ(64, os->ByteCount()); + ASSERT_EQ(64, os->Reserve(32)); + ASSERT_EQ(96, os->ByteCount()); + ASSERT_EQ(3u, os->_buf_list.size()); + } +} + +TEST_F(WriteBufferTest, SetData) +{ + { + WriteBufferPtr os(new WriteBuffer()); + ASSERT_EQ(0, os->Reserve(10)); + os->SetData(0, _block, 10); + } + { + WriteBufferPtr os(new WriteBuffer()); + ASSERT_EQ(0, os->Reserve(10)); + ASSERT_EQ(10, os->Reserve(32)); + os->SetData(10, _block, 32); + } +} + +class PBSerDeserTest : public ::testing::Test +{ +public: + PBSerDeserTest() {} + virtual ~PBSerDeserTest() {} + virtual void SetUp() { + _block_size = TranBufPool::block_size(); + std::string str(5000, 'x'); + _test_data.set_v1(12); + _test_data.set_v2(34); + _test_data.set_v3(true); + _test_data.set_v4(str); + _test_data.set_v5("hello"); + } + virtual void TearDown() { + } + + int _block_size; + ::sofa::pbrpc::test::TestData _test_data; +}; + +TEST_F(PBSerDeserTest, SerDeser) +{ + RpcMessageHeader header; + int header_size = sizeof(header); + RpcMeta meta; + meta.set_type(RpcMeta::REQUEST); + meta.set_sequence_id(1); + meta.set_method("TestService.Echo"); + + WriteBufferPtr os(new WriteBuffer()); + ASSERT_EQ(0, os->Reserve(header_size)); + ASSERT_EQ(header_size, os->ByteCount()); + ASSERT_TRUE(meta.SerializeToZeroCopyStream(os.get())); + int meta_size = os->ByteCount() - header_size; + ASSERT_TRUE(_test_data.SerializeToZeroCopyStream(os.get())); + int data_size = os->ByteCount() - header_size - meta_size; + SLOG(NOTICE, "os->TotalCapacity = %d, os->ByteCount = %d", + os->TotalCapacity(), os->ByteCount()); + int total_size = header_size + meta_size + data_size; + + ReadBufferPtr is(new ReadBuffer()); + os->SwapOut(is.get()); + ASSERT_EQ(0, os->TotalCapacity()); + ASSERT_EQ(0, os->ByteCount()); + ASSERT_EQ(total_size, is->TotalCount()); + ASSERT_EQ(0, is->ByteCount()); + SLOG(NOTICE, "is->TotalCount = %d, os->ByteCount = %d", + is->TotalCount(), is->ByteCount()); + + ASSERT_TRUE(is->Skip(header_size)); + ASSERT_EQ(header_size, is->ByteCount()); + + RpcMeta new_meta; + ASSERT_TRUE(new_meta.ParseFromBoundedZeroCopyStream(is.get(), meta_size)); + ASSERT_EQ(header_size + meta_size, is->ByteCount()); + ASSERT_EQ(RpcMeta::REQUEST, new_meta.type()); + ASSERT_EQ(1u, new_meta.sequence_id()); + ASSERT_EQ("TestService.Echo", new_meta.method()); + ASSERT_EQ(meta.method().size(), new_meta.method().size()); + + ::sofa::pbrpc::test::TestData new_data; + ASSERT_TRUE(new_data.ParseFromBoundedZeroCopyStream(is.get(), data_size)); + ASSERT_EQ(total_size, is->ByteCount()); + ASSERT_EQ(12, new_data.v1()); + ASSERT_EQ(_test_data.v5().size(), new_data.v5().size()); + std::string old_str, new_str; + ASSERT_TRUE(_test_data.SerializeToString(&old_str)); + ASSERT_TRUE(new_data.SerializeToString(&new_str)); + ASSERT_EQ(old_str, new_str); + + SLOG(NOTICE, "meta_size=%d, data_size=%lld", meta_size, data_size); +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/unit-test/test_closure.cc b/unit-test/test_closure.cc new file mode 100644 index 0000000..20c3004 --- /dev/null +++ b/unit-test/test_closure.cc @@ -0,0 +1,290 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include +#include + +using namespace std; +using namespace sofa::pbrpc; + +class ClosureTest : public testing::Test { +public: + void SetA123Method() { a_ = 123; } + static void SetA123Function() { current_instance_->a_ = 123; } + + void SetAMethod(int a) { a_ = a; } + void SetCMethod(string c) { c_ = c; } + + static void SetAFunction(int a) { current_instance_->a_ = a; } + static void SetCFunction(string c) { current_instance_->c_ = c; } + + void SetABMethod(int a, const char* b) { a_ = a; b_ = b; } + static void SetABFunction(int a, const char* b) { + current_instance_->a_ = a; + current_instance_->b_ = b; + } + + void SetABCMethod(int a, const char* b, std::string c) { + a_ = a; b_ = b; c_ = c; + } + static void SetABCFunction(int a, const char* b, std::string c) { + current_instance_->a_ = a; + current_instance_->b_ = b; + current_instance_->c_ = c; + } + + void SetABCDMethod(int a, const char* b, const std::string& c, double d) { + a_ = a; b_ = b; c_ = c; d_ = d; + } + static void SetABCDFunction(int a, const char* b, const std::string& c, double d) { + current_instance_->a_ = a; + current_instance_->b_ = b; + current_instance_->c_ = c; + current_instance_->d_ = d; + } + + virtual void SetUp() { + current_instance_ = this; + a_ = 0; + b_ = NULL; + c_.clear(); + d_ = 0.0; + permanent_closure_ = NULL; + } + + void DeleteClosureInCallback() { + delete permanent_closure_; + } + + int a_; + const char* b_; + string c_; + double d_; + google::protobuf::Closure* permanent_closure_; + + static ClosureTest* current_instance_; +}; + +ClosureTest* ClosureTest::current_instance_ = NULL; + +TEST_F(ClosureTest, TestClosureFunction0) { + google::protobuf::Closure* closure = NewClosure(&SetA123Function); + EXPECT_NE(123, a_); + closure->Run(); + EXPECT_EQ(123, a_); +} + +TEST_F(ClosureTest, TestClosureMethod0) { + google::protobuf::Closure* closure = NewClosure(current_instance_, + &ClosureTest::SetA123Method); + EXPECT_NE(123, a_); + closure->Run(); + EXPECT_EQ(123, a_); +} + +TEST_F(ClosureTest, TestClosureFunction1) { + google::protobuf::Closure* closure = NewClosure(&SetAFunction, 456); + EXPECT_NE(456, a_); + closure->Run(); + EXPECT_EQ(456, a_); +} + +TEST_F(ClosureTest, TestClosureMethod1) { + google::protobuf::Closure* closure = NewClosure(current_instance_, + &ClosureTest::SetAMethod, 456); + EXPECT_NE(456, a_); + closure->Run(); + EXPECT_EQ(456, a_); +} + +TEST_F(ClosureTest, TestClosureFunction1String) { + google::protobuf::Closure* closure = NewClosure(&SetCFunction, string("test")); + EXPECT_NE("test", c_); + closure->Run(); + EXPECT_EQ("test", c_); +} + +TEST_F(ClosureTest, TestClosureMethod1String) { + google::protobuf::Closure* closure = NewClosure(current_instance_, + &ClosureTest::SetCMethod, string("test")); + EXPECT_NE("test", c_); + closure->Run(); + EXPECT_EQ("test", c_); +} + +TEST_F(ClosureTest, TestClosureFunction2) { + const char* cstr = "hello"; + google::protobuf::Closure* closure = NewClosure(&SetABFunction, 789, cstr); + EXPECT_NE(789, a_); + EXPECT_NE(cstr, b_); + closure->Run(); + EXPECT_EQ(789, a_); + EXPECT_EQ(cstr, b_); +} + +TEST_F(ClosureTest, TestClosureMethod2) { + const char* cstr = "hello"; + google::protobuf::Closure* closure = NewClosure(current_instance_, + &ClosureTest::SetABMethod, 789, cstr); + EXPECT_NE(789, a_); + EXPECT_NE(cstr, b_); + closure->Run(); + EXPECT_EQ(789, a_); + EXPECT_EQ(cstr, b_); +} + +TEST_F(ClosureTest, TestClosureFunction3) { + const char* cstr = "hello"; + std::string str = cstr; + google::protobuf::Closure* closure = NewClosure(&SetABCFunction, 789, cstr, str); + EXPECT_NE(789, a_); + EXPECT_NE(cstr, b_); + EXPECT_NE(str, c_); + closure->Run(); + EXPECT_EQ(789, a_); + EXPECT_EQ(cstr, b_); + EXPECT_EQ(str, c_); +} + +TEST_F(ClosureTest, TestClosureMethod3) { + const char* cstr = "hello"; + std::string str = cstr; + google::protobuf::Closure* closure = NewClosure(current_instance_, + &ClosureTest::SetABCMethod, 789, cstr, str); + EXPECT_NE(789, a_); + EXPECT_NE(cstr, b_); + EXPECT_NE(str, c_); + closure->Run(); + EXPECT_EQ(789, a_); + EXPECT_EQ(cstr, b_); + EXPECT_EQ(str, c_); +} + +TEST_F(ClosureTest, TestClosureFunction4) { + const char* cstr = "hello"; + std::string str = cstr; + google::protobuf::Closure* closure = NewClosure(&SetABCDFunction, 789, cstr, str, 1.0); + EXPECT_NE(789, a_); + EXPECT_NE(cstr, b_); + EXPECT_NE(str, c_); + EXPECT_NE(1.0, d_); + closure->Run(); + EXPECT_EQ(789, a_); + EXPECT_EQ(cstr, b_); + EXPECT_EQ(str, c_); + EXPECT_EQ(1.0, d_); +} + +TEST_F(ClosureTest, TestClosureMethod4) { + const char* cstr = "hello"; + std::string str = cstr; + google::protobuf::Closure* closure = NewClosure(current_instance_, + &ClosureTest::SetABCDMethod, 789, cstr, str, 1.0); + EXPECT_NE(789, a_); + EXPECT_NE(cstr, b_); + EXPECT_NE(str, c_); + EXPECT_NE(1.0, d_); + closure->Run(); + EXPECT_EQ(789, a_); + EXPECT_EQ(cstr, b_); + EXPECT_EQ(str, c_); + EXPECT_EQ(1.0, d_); +} + +// Repeat all of the above with NewPermanentClosure() + +TEST_F(ClosureTest, TestPermanentClosureFunction0) { + google::protobuf::Closure* closure = NewPermanentClosure(&SetA123Function); + EXPECT_NE(123, a_); + closure->Run(); + EXPECT_EQ(123, a_); + a_ = 0; + closure->Run(); + EXPECT_EQ(123, a_); + delete closure; +} + +TEST_F(ClosureTest, TestPermanentClosureMethod0) { + google::protobuf::Closure* closure = NewPermanentClosure(current_instance_, + &ClosureTest::SetA123Method); + EXPECT_NE(123, a_); + closure->Run(); + EXPECT_EQ(123, a_); + a_ = 0; + closure->Run(); + EXPECT_EQ(123, a_); + delete closure; +} + +TEST_F(ClosureTest, TestPermanentClosureFunction1) { + google::protobuf::Closure* closure = NewPermanentClosure(&SetAFunction, 456); + EXPECT_NE(456, a_); + closure->Run(); + EXPECT_EQ(456, a_); + a_ = 0; + closure->Run(); + EXPECT_EQ(456, a_); + delete closure; +} + +TEST_F(ClosureTest, TestPermanentClosureMethod1) { + google::protobuf::Closure* closure = NewPermanentClosure(current_instance_, + &ClosureTest::SetAMethod, 456); + EXPECT_NE(456, a_); + closure->Run(); + EXPECT_EQ(456, a_); + a_ = 0; + closure->Run(); + EXPECT_EQ(456, a_); + delete closure; +} + +TEST_F(ClosureTest, TestPermanentClosureFunction2) { + const char* cstr = "hello"; + google::protobuf::Closure* closure = NewPermanentClosure(&SetABFunction, 789, cstr); + EXPECT_NE(789, a_); + EXPECT_NE(cstr, b_); + closure->Run(); + EXPECT_EQ(789, a_); + EXPECT_EQ(cstr, b_); + a_ = 0; + b_ = NULL; + closure->Run(); + EXPECT_EQ(789, a_); + EXPECT_EQ(cstr, b_); + delete closure; +} + +TEST_F(ClosureTest, TestPermanentClosureMethod2) { + const char* cstr = "hello"; + google::protobuf::Closure* closure = NewPermanentClosure(current_instance_, + &ClosureTest::SetABMethod, 789, cstr); + EXPECT_NE(789, a_); + EXPECT_NE(cstr, b_); + closure->Run(); + EXPECT_EQ(789, a_); + EXPECT_EQ(cstr, b_); + a_ = 0; + b_ = NULL; + closure->Run(); + EXPECT_EQ(789, a_); + EXPECT_EQ(cstr, b_); + delete closure; +} + +TEST_F(ClosureTest, TestPermanentClosureDeleteInCallback) { + permanent_closure_ = NewPermanentClosure((ClosureTest*) this, + &ClosureTest::DeleteClosureInCallback); + permanent_closure_->Run(); +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/unit-test/test_common.cc b/unit-test/test_common.cc new file mode 100644 index 0000000..cda5868 --- /dev/null +++ b/unit-test/test_common.cc @@ -0,0 +1,54 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include +#include + +using namespace sofa; + +class CommonTest : public ::testing::Test +{ +protected: + CommonTest(){}; + virtual ~CommonTest(){}; + virtual void SetUp() { + //Called befor every TEST_F(CommonTest, *) + }; + virtual void TearDown() { + //Called after every TEST_F(CommonTest, *) + }; +}; + +TEST_F(CommonTest, test_log) +{ + sofa::pbrpc::internal::set_log_level(sofa::pbrpc::LOG_LEVEL_NOTICE); + int flag_notice = 0; + SLOG(NOTICE, "notice message: %d: %s", ++flag_notice, "should be logged"); + ASSERT_EQ(1, flag_notice); + int flag_trace = 0; + SLOG(TRACE, "trace message: %d: %s", ++flag_trace, "should not be logged"); + ASSERT_EQ(0, flag_trace); +} + +TEST_F(CommonTest, test_check) +{ + int value = 1; + SCHECK_EQ(1, value); + SCHECK_LE(1, value); + SCHECK_LE(0, value); + SCHECK_LT(0, value); + SCHECK_GE(1, value); + SCHECK_GE(2, value); + SCHECK_GT(2, value); +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/unit-test/test_data.proto b/unit-test/test_data.proto new file mode 100644 index 0000000..1fc7305 --- /dev/null +++ b/unit-test/test_data.proto @@ -0,0 +1,9 @@ +package sofa.pbrpc.test; + +message TestData { + required int32 v1 = 1; + optional int64 v2 = 2; + optional bool v3 = 3; + optional bytes v4 = 4; + optional string v5 = 5; +} diff --git a/unit-test/test_epoll_support.cc b/unit-test/test_epoll_support.cc new file mode 100644 index 0000000..cde9e90 --- /dev/null +++ b/unit-test/test_epoll_support.cc @@ -0,0 +1,35 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include +#include + +class EpollSupportTest: public ::testing::Test {}; + +TEST_F(EpollSupportTest, test) +{ + std::string output; +#if defined(BOOST_ASIO_HAS_IOCP) + output = "iocp" ; +#elif defined(BOOST_ASIO_HAS_EPOLL) + output = "epoll" ; +#elif defined(BOOST_ASIO_HAS_KQUEUE) + output = "kqueue" ; +#elif defined(BOOST_ASIO_HAS_DEV_POLL) + output = "/dev/poll" ; +#else + output = "select" ; +#endif + ASSERT_EQ("epoll", output); +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/unit-test/test_ext_closure.cc b/unit-test/test_ext_closure.cc new file mode 100644 index 0000000..b188a95 --- /dev/null +++ b/unit-test/test_ext_closure.cc @@ -0,0 +1,829 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include +#include +#include + +using namespace ::sofa::pbrpc; + +// preArg +void test0() { + printf("test0()\r\n"); +} +void test1(char preA) { + printf("test1(),preA=%c\r\n", preA); +} +void test2(char preA, short preB) { + printf("test2(),preA=%c,preB=%d\r\n", preA, preB); +} +void test3(char preA, short preB, int preC) { + printf("test3(),preA=%c,preB=%d,preC=%d\r\n", preA, preB, preC); +} + +// preArg_Arg(last one) +void test0_1(char a) { + printf("test0_1(),a=%c\r\n", a); +} +void test1_1(char preA, short b) { + printf("test1_1(),preA=%c,b=%d\r\n", preA, b); +} +void test2_1(char preA, short preB, int c) { + printf("test2_1(),preA=%c,preB=%d,c=%d\r\n", preA, preB, c); +} + +// preArg_Arg(last) +void test0_2(char a, short b) { + printf("test0_2(),a=%c,b=%d\r\n", a, b); +} +void test1_2(char preA, char a, int b) { + printf("test1_2(),preA=%c,a=%c,b=%d\n", preA, a, b); +} + +// preArg_Arg(last) +void test0_3(char a, short b, int c) { + printf("test0_3(),a=%c,b=%d,c=%d\r\n", a, b, c); +} + +//----------ExtClosure--------- +// preArg +char Rtest0() { + printf("Rtest0()\r\n"); + return 'a'; +} +char Rtest1(char preA) { + printf("Rtest1(),preA=%c\r\n", preA); + return preA; +} +char Rtest2(char preA, short preB) { + printf("Rtest2(),preA=%c,preB=%d\r\n", preA, preB); + return preA; +} +char Rtest3(char preA, short preB, int preC) { + printf("Rtest3(),preA=%c,preB=%d,preC=%d\r\n", preA, preB, preC); + return preA; +} + +// preArg_Arg(last one) +short Rtest0_1(char a) { + printf("Rtest0_1(),a=%c\r\n", a); + return short(980); +} + +short Rtest1_1(char preA, short b) { + printf("Rtest1_1(),preA=%c,b=%d\r\n", preA, b); + return b; +} + +short Rtest2_1(char preA, short preB, int c) { + printf("Rtest2_1(),preA=%c,preB=%d,c=%d\r\n", preA, preB, c); + return preB; +} + +// preArg_Arg(last) +int Rtest0_2(char a, short b) { + printf("Rtest0_2(),a=%c,b=%d\r\n", a, b); + return int(9900); +} +int Rtest1_2(char preA, char a, int b) { + printf("Rtest1_2(),preA=%c,a=%c,b=%d\r\n", preA, a, b); + return b; +} + +// preArg_Arg(last) +unsigned int Rtest0_3(char a, short b, int c) { + printf("Rtest0_3(),a=%c,b=%d,c=%d\r\n", a, b, c); + return (unsigned int)c; +} + +class CTest +{ +public: + CTest() {} + virtual ~CTest() {} + + // preArg + void test0() { + printf("test0()\r\n"); + } + void test1(char preA) { + printf("test1(),preA=%c\r\n", preA); + } + void test2(char preA, short preB) { + printf("test2(),preA=%c,preB=%d\r\n", preA, preB); + } + void test3(char preA, short preB, int preC) { + printf("test3(),preA=%c,preB=%d,preC=%d\r\n", preA, preB, preC); + } + + // preArg_Arg(last one) + void test0_1(char a) { + printf("test0_1(),a=%c\r\n", a); + } + void test1_1(char preA, short b) { + printf("test1_1(),preA=%c,b=%d\r\n", preA, b); + } + void test2_1(char preA, short preB, int c) { + printf("test2_1(),preA=%c,preB=%d,c=%d\r\n", preA, preB, c); + } + + // preArg_Arg(last) + void test0_2(char a, short b) { + printf("test0_2(),a=%c,b=%d\r\n", a, b); + } + void test1_2(char preA, char a, int b) { + printf("test1_2(),preA=%c,a=%c,b=%d\n", preA, a, b); + } + + // preArg_Arg(last) + void test0_3(char a, short b, int c) { + printf("test0_3(),a=%c,b=%d,c=%d\r\n", a, b, c); + } + + //----------ExtClosure--------- + // preArg + char Rtest0() { + printf("Rtest0()\r\n"); + return 'a'; + } + char Rtest1(char preA) { + printf("Rtest1(),preA=%c\r\n", preA); + return preA; + } + char Rtest2(char preA, short preB) { + printf("Rtest2(),preA=%c,preB=%d\r\n", preA, preB); + return preA; + } + char Rtest3(char preA, short preB, int preC) { + printf("Rtest3(),preA=%c,preB=%d,preC=%d\r\n", preA, preB, preC); + return preA; + } + + // preArg_Arg(last one) + short Rtest0_1(char a) { + printf("Rtest0_1(),a=%c\r\n", a); + return short(980); + } + short Rtest1_1(char preA, short b) { + printf("Rtest1_1(),preA=%c,b=%d\r\n", preA, b); + return b; + } + short Rtest2_1(char preA, short preB, int c) { + printf("Rtest2_1(),preA=%c,preB=%d,c=%d\r\n", preA, preB, c); + return preB; + } + + // preArg_Arg(last) + int Rtest0_2(char a, short b) { + printf("Rtest0_2(),a=%c,b=%d\r\n", a, b); + return int(9900); + } + int Rtest1_2(char preA, char a, int b) { + printf("Rtest1_2(),preA=%c,a=%c,b=%d\r\n", preA, a, b); + return b; + } + + // preArg_Arg(last) + unsigned int Rtest0_3(char a, short b, int c) { + printf("Rtest0_3(),a=%c,b=%d,c=%d\r\n", a, b, c); + return (unsigned int) c; + } +}; +TEST(ExtClosure, ExtClosure) +{ + printf("\r\n==============test NewExtClosure===============\r\n"); + + ASSERT_TRUE(true); + + // Closure0 + ExtClosure * pcb = NewExtClosure(test0); + ASSERT_TRUE(pcb->IsSelfDelete()); + pcb->Run(); + + pcb = NewExtClosure(test1, 'a'); + pcb->Run(); + + pcb = NewExtClosure(test2, char('a'), short(456)); + pcb->Run(); + + pcb = NewExtClosure(test3, char('a'), short(456), int(9800)); + pcb->Run(); + + // Closure1 + ExtClosure* pcb0_1 = NewExtClosure(test0_1); + pcb0_1->Run('a'); + + ExtClosure* pcb1_1 = NewExtClosure(test1_1, 'a'); + pcb1_1->Run(780); + + ExtClosure* pcb2_1 = NewExtClosure(test2_1, char('a'), short(7800)); + pcb2_1->Run(9800); + + // Closure2 + ExtClosure* pcb0_2 = NewExtClosure(test0_2); + pcb0_2->Run('a', 8900); + + ExtClosure* pcb1_2 = NewExtClosure(test1_2, 'a'); + pcb1_2->Run('b', 780); + + // Closure3 + ExtClosure* pcb0_3 = NewExtClosure(test0_3); + pcb0_3->Run('a', 456, 78909); + + //------ExtClosure------------ + printf("\r\n------ExtClosure------------\r\n"); + + // Closure0 + ExtClosure* pRcb = NewExtClosure(Rtest0); + char r0 = pRcb->Run(); + EXPECT_EQ('a', r0); + + pRcb = NewExtClosure(Rtest1, 'a'); + r0 = pRcb->Run(); + EXPECT_EQ('a', r0); + + pRcb = NewExtClosure(Rtest2, char('a'), short(456)); + r0 = pRcb->Run(); + EXPECT_EQ('a', r0); + + pRcb = NewExtClosure(Rtest3, char('a'), short(456), int(9800)); + r0 = pRcb->Run(); + EXPECT_EQ('a', r0); + + // Closure1 + ExtClosure* pRcb0_1 = NewExtClosure(Rtest0_1); + short r1 = pRcb0_1->Run('a'); + EXPECT_EQ(980, r1); + + ExtClosure* pRcb1_1 = NewExtClosure(Rtest1_1, 'a'); + r1 = pRcb1_1->Run(780); + EXPECT_EQ(780, r1); + + ExtClosure* pRcb2_1 = NewExtClosure(Rtest2_1, char('a'), short(7800)); + r1 = pRcb2_1->Run(9800); + EXPECT_EQ(7800, r1); + + // Closure2 + ExtClosure* pRcb0_2 = NewExtClosure(Rtest0_2); + int r2 = pRcb0_2->Run('a', 8900); + EXPECT_EQ(9900, r2); + + ExtClosure* pRcb1_2 = NewExtClosure(Rtest1_2, 'a'); + r2 = pRcb1_2->Run('b', 780); + EXPECT_EQ(780, r2); + + // Closure3 + ExtClosure* pRcb0_3 = NewExtClosure(Rtest0_3); + unsigned int r3 = pRcb0_3->Run('a', 456, 78909); + EXPECT_EQ(78909U, r3); +} + +TEST(ExtClosure, PermanentClosure) +{ + printf("\r\n==============test NewPermanentExtClosure===============\r\n"); + // Closure0 + ExtClosure* pcb = NewPermanentExtClosure(test0); + ASSERT_FALSE(pcb->IsSelfDelete()); + pcb->Run(); + delete pcb; + + pcb = NewPermanentExtClosure(test1, 'a'); + pcb->Run(); + delete pcb; + + pcb = NewPermanentExtClosure(test2, char('a'), short(456)); + pcb->Run(); + delete pcb; + + pcb = NewPermanentExtClosure(test3, char('a'), short(456), int(9800)); + pcb->Run(); + delete pcb; + + // Closure1 + ExtClosure* pcb0_1 = NewPermanentExtClosure(test0_1); + pcb0_1->Run('a'); + delete pcb0_1; + + ExtClosure* pcb1_1 = NewPermanentExtClosure(test1_1, 'a'); + pcb1_1->Run(780); + delete pcb1_1; + + ExtClosure* pcb2_1 = NewPermanentExtClosure(test2_1, char('a'), short(7800)); + pcb2_1->Run(9800); + delete pcb2_1; + + // Closure2 + ExtClosure* pcb0_2 = NewPermanentExtClosure(test0_2); + pcb0_2->Run('a', 8900); + delete pcb0_2; + + ExtClosure* pcb1_2 = NewPermanentExtClosure(test1_2, 'a'); + pcb1_2->Run('b', 780); + delete pcb1_2; + + // Closure3 + ExtClosure* pcb0_3 = NewPermanentExtClosure(test0_3); + pcb0_3->Run('a', 456, 78909); + delete pcb0_3; + + //------ExtClosure------------ + printf("\r\n------ExtClosure------------\r\n"); + + // Closure0 + ExtClosure* pRcb = NewPermanentExtClosure(Rtest0); + char r0 = pRcb->Run(); + EXPECT_EQ('a', r0); + delete pRcb; + + pRcb = NewPermanentExtClosure(Rtest1, 'a'); + r0 = pRcb->Run(); + EXPECT_EQ('a', r0); + delete pRcb; + + pRcb = NewPermanentExtClosure(Rtest2, char('a'), short(456)); + r0 = pRcb->Run(); + EXPECT_EQ('a', r0); + delete pRcb; + + pRcb = NewPermanentExtClosure(Rtest3, char('a'), short(456), int(9800)); + r0 = pRcb->Run(); + EXPECT_EQ('a', r0); + delete pRcb; + + // Closure1 + ExtClosure* pRcb0_1 = NewPermanentExtClosure(Rtest0_1); + short r1 = pRcb0_1->Run('a'); + EXPECT_EQ(980, r1); + delete pRcb0_1; + + ExtClosure* pRcb1_1 = NewPermanentExtClosure(Rtest1_1, 'a'); + r1 = pRcb1_1->Run(780); + EXPECT_EQ(780, r1); + delete pRcb1_1; + + ExtClosure* pRcb2_1 = NewPermanentExtClosure(Rtest2_1, char('a'), short(7800)); + r1 = pRcb2_1->Run(9800); + EXPECT_EQ(7800, r1); + delete pRcb2_1; + + // Closure2 + ExtClosure* pRcb0_2 = NewPermanentExtClosure(Rtest0_2); + int r2 = pRcb0_2->Run('a', 8900); + EXPECT_EQ(9900, r2); + delete pRcb0_2; + + ExtClosure* pRcb1_2 = NewPermanentExtClosure(Rtest1_2, 'a'); + r2 = pRcb1_2->Run('b', 780); + EXPECT_EQ(780, r2); + delete pRcb1_2; + + // Closure3 + ExtClosure* pRcb0_3 = NewPermanentExtClosure(Rtest0_3); + unsigned int r3 = pRcb0_3->Run('a', 456, 78909); + EXPECT_EQ(78909U, r3); + delete pRcb0_3; +} + +TEST(ExtClosure, ClassClosure) +{ + printf("\r\n==============test NewExtClosure(Class)===============\r\n"); + + CTest obj; + + // Closure0 + ExtClosure* pcb = NewExtClosure(&obj, &CTest::test0); + pcb->Run(); + + pcb = NewExtClosure(&obj, &CTest::test1, 'a'); + pcb->Run(); + + pcb = NewExtClosure(&obj, &CTest::test2, char('a'), short(456)); + pcb->Run(); + + pcb = NewExtClosure(&obj, &CTest::test3, char('a'), short(456), int(9800)); + pcb->Run(); + + // Closure1 + ExtClosure* pcb0_1 = NewExtClosure(&obj, &CTest::test0_1); + pcb0_1->Run('a'); + + ExtClosure* pcb1_1 = NewExtClosure(&obj, &CTest::test1_1, 'a'); + pcb1_1->Run(short(780)); + + ExtClosure* pcb2_1 = NewExtClosure(&obj, &CTest::test2_1, char('a'), short(7800)); + pcb2_1->Run(9800); + + // Closure2 + ExtClosure* pcb0_2 = NewExtClosure(&obj, &CTest::test0_2); + pcb0_2->Run('a', 8900); + + ExtClosure* pcb1_2 = NewExtClosure(&obj, &CTest::test1_2, 'a'); + pcb1_2->Run('b', 780); + + // Closure3 + ExtClosure* pcb0_3 = NewExtClosure(&obj, &CTest::test0_3); + pcb0_3->Run('a', 456, 78909); + + //------ExtClosure------------ + printf("\r\n------ExtClosure------------\r\n"); + + // Closure0 + ExtClosure* pRcb = NewExtClosure(&obj, &CTest::Rtest0); + char r0 = pRcb->Run(); + EXPECT_EQ('a', r0); + + pRcb = NewExtClosure(&obj, &CTest::Rtest1, 'a'); + r0 = pRcb->Run(); + EXPECT_EQ('a', r0); + + pRcb = NewExtClosure(&obj, &CTest::Rtest2, char('a'), short(456)); + r0 = pRcb->Run(); + EXPECT_EQ('a', r0); + + pRcb = NewExtClosure(&obj, &CTest::Rtest3, char('a'), short(456), int(9800)); + r0 = pRcb->Run(); + EXPECT_EQ('a', r0); + + // Closure1 + ExtClosure* pRcb0_1 = NewExtClosure(&obj, &CTest::Rtest0_1); + short r1 = pRcb0_1->Run('a'); + EXPECT_EQ(980, r1); + + ExtClosure* pRcb1_1 = NewExtClosure(&obj, &CTest::Rtest1_1, 'a'); + r1 = pRcb1_1->Run(780); + EXPECT_EQ(780, r1); + + ExtClosure* pRcb2_1 = NewExtClosure(&obj, &CTest::Rtest2_1, char('a'), short(7800)); + r1 = pRcb2_1->Run(9800); + EXPECT_EQ(7800, r1); + + // Closure2 + ExtClosure* pRcb0_2 = + NewExtClosure(&obj, &CTest::Rtest0_2); + int r2 = pRcb0_2->Run('a', 8900); + EXPECT_EQ(9900, r2); + + ExtClosure* pRcb1_2 = NewExtClosure(&obj, &CTest::Rtest1_2, 'a'); + r2 = pRcb1_2->Run('b', 780); + EXPECT_EQ(780, r2); + + // Closure3 + ExtClosure* pRcb0_3 = NewExtClosure(&obj, &CTest::test0_3); + pRcb0_3->Run('a', 456, 78909); +} + +TEST(ExtClosure, ClassPermanentClosure) +{ + printf("\r\n==============test NewExtClosure(Class)===============\r\n"); + + CTest obj; + + // Closure0 + ExtClosure* pcb = NewPermanentExtClosure(&obj, &CTest::test0); + pcb->Run(); + delete pcb; + + pcb = NewPermanentExtClosure(&obj, &CTest::test1, 'a'); + pcb->Run(); + delete pcb; + + pcb = NewPermanentExtClosure(&obj, &CTest::test2, char('a'), short(456)); + pcb->Run(); + delete pcb; + + pcb = NewPermanentExtClosure(&obj, &CTest::test3, char('a'), short(456), int(9800)); + pcb->Run(); + delete pcb; + + // Closure1 + ExtClosure* pcb0_1 = NewPermanentExtClosure(&obj, &CTest::test0_1); + pcb0_1->Run('a'); + delete pcb0_1; + + ExtClosure* pcb1_1 = NewPermanentExtClosure(&obj, &CTest::test1_1, 'a'); + pcb1_1->Run(short(780)); + + ExtClosure* pcb2_1 = + NewPermanentExtClosure(&obj, &CTest::test2_1, char('a'), short(7800)); + pcb2_1->Run(9800); + + // Closure2 + ExtClosure* pcb0_2 = NewPermanentExtClosure(&obj, &CTest::test0_2); + pcb0_2->Run('a', 8900); + + ExtClosure* pcb1_2 = NewPermanentExtClosure(&obj, &CTest::test1_2, 'a'); + pcb1_2->Run('b', 780); + + // Closure3 + ExtClosure* pcb0_3 = NewPermanentExtClosure(&obj, &CTest::test0_3); + pcb0_3->Run('a', 456, 78909); + + //------ExtClosure------------ + printf("\r\n------ExtClosure------------\r\n"); + + // Closure0 + ExtClosure* pRcb = NewPermanentExtClosure(&obj, &CTest::Rtest0); + char r0 = pRcb->Run(); + EXPECT_EQ('a', r0); + + pRcb = NewPermanentExtClosure(&obj, &CTest::Rtest1, 'a'); + r0 = pRcb->Run(); + EXPECT_EQ('a', r0); + + pRcb = NewPermanentExtClosure(&obj, &CTest::Rtest2, char('a'), short(456)); + r0 = pRcb->Run(); + EXPECT_EQ('a', r0); + + pRcb = NewPermanentExtClosure(&obj, &CTest::Rtest3, char('a'), short(456), int(9800)); + r0 = pRcb->Run(); + EXPECT_EQ('a', r0); + + // Closure1 + ExtClosure* pRcb0_1 = NewPermanentExtClosure(&obj, &CTest::Rtest0_1); + short r1 = pRcb0_1->Run('a'); + EXPECT_EQ(980, r1); + + ExtClosure* pRcb1_1 = NewPermanentExtClosure(&obj, &CTest::Rtest1_1, 'a'); + r1 = pRcb1_1->Run(780); + EXPECT_EQ(780, r1); + + ExtClosure* pRcb2_1 = + NewPermanentExtClosure(&obj, &CTest::Rtest2_1, char('a'), short(7800)); + r1 = pRcb2_1->Run(9800); + EXPECT_EQ(7800, r1); + + // Closure2 + ExtClosure* pRcb0_2 = + NewPermanentExtClosure(&obj, &CTest::Rtest0_2); + int r2 = pRcb0_2->Run('a', 8900); + EXPECT_EQ(9900, r2); + + ExtClosure* pRcb1_2 = NewPermanentExtClosure(&obj, &CTest::Rtest1_2, 'a'); + r2 = pRcb1_2->Run('b', 780); + EXPECT_EQ(780, r2); + + // Closure3 + ExtClosure* pRcb0_3 = NewPermanentExtClosure(&obj, &CTest::Rtest0_3); + unsigned int r3 = pRcb0_3->Run('a', 456, 78909); + EXPECT_EQ(78909U, r3); +} + +TEST(ExtClosure, ClassSharedPtrClosure) +{ + printf("\r\n==============test NewExtClosure(ClassPtr)===============\r\n"); + + ::sofa::pbrpc::shared_ptr obj(new CTest()); + + // Closure0 + ExtClosure* pcb = NewExtClosure(obj, &CTest::test0); + pcb->Run(); + + pcb = NewExtClosure(obj, &CTest::test1, 'a'); + pcb->Run(); + + const ::sofa::pbrpc::shared_ptr& obj_const_ref = obj; + pcb = NewExtClosure(obj_const_ref, &CTest::test1, 'a'); + pcb->Run(); + + pcb = NewExtClosure(obj, &CTest::test2, char('a'), short(456)); + pcb->Run(); + + pcb = NewExtClosure(obj, &CTest::test3, char('a'), short(456), int(9800)); + pcb->Run(); + + // Closure1 + ExtClosure* pcb0_1 = NewExtClosure(obj, &CTest::test0_1); + pcb0_1->Run('a'); + + ExtClosure* pcb1_1 = NewExtClosure(obj, &CTest::test1_1, 'a'); + pcb1_1->Run(short(780)); + + ExtClosure* pcb2_1 = NewExtClosure(obj, &CTest::test2_1, char('a'), short(7800)); + pcb2_1->Run(9800); + + // Closure2 + ExtClosure* pcb0_2 = NewExtClosure(obj, &CTest::test0_2); + pcb0_2->Run('a', 8900); + + ExtClosure* pcb1_2 = NewExtClosure(obj, &CTest::test1_2, 'a'); + pcb1_2->Run('b', 780); + + // Closure3 + ExtClosure* pcb0_3 = NewExtClosure(obj, &CTest::test0_3); + pcb0_3->Run('a', 456, 78909); + + //------ExtClosure------------ + printf("\r\n------ExtClosure------------\r\n"); + + // Closure0 + ExtClosure* pRcb = NewExtClosure(obj, &CTest::Rtest0); + char r0 = pRcb->Run(); + EXPECT_EQ('a', r0); + + pRcb = NewExtClosure(obj, &CTest::Rtest1, 'a'); + r0 = pRcb->Run(); + EXPECT_EQ('a', r0); + + pRcb = NewExtClosure(obj, &CTest::Rtest2, char('a'), short(456)); + r0 = pRcb->Run(); + EXPECT_EQ('a', r0); + + pRcb = NewExtClosure(obj, &CTest::Rtest3, char('a'), short(456), int(9800)); + r0 = pRcb->Run(); + EXPECT_EQ('a', r0); + + // Closure1 + ExtClosure* pRcb0_1 = NewExtClosure(obj, &CTest::Rtest0_1); + short r1 = pRcb0_1->Run('a'); + EXPECT_EQ(980, r1); + + ExtClosure* pRcb1_1 = NewExtClosure(obj, &CTest::Rtest1_1, 'a'); + r1 = pRcb1_1->Run(780); + EXPECT_EQ(780, r1); + + ExtClosure* pRcb2_1 = NewExtClosure(obj, &CTest::Rtest2_1, char('a'), short(7800)); + r1 = pRcb2_1->Run(9800); + EXPECT_EQ(7800, r1); + + // Closure2 + ExtClosure* pRcb0_2 = + NewExtClosure(obj, &CTest::Rtest0_2); + int r2 = pRcb0_2->Run('a', 8900); + EXPECT_EQ(9900, r2); + + ExtClosure* pRcb1_2 = NewExtClosure(obj, &CTest::Rtest1_2, 'a'); + r2 = pRcb1_2->Run('b', 780); + EXPECT_EQ(780, r2); + + // Closure3 + ExtClosure* pRcb0_3 = NewExtClosure(obj, &CTest::test0_3); + pRcb0_3->Run('a', 456, 78909); +} + +#if 0 +class Performance : public testing::Test {}; + +const int kLoopCount = 1000000; + +void NullFunction() +{ +} + +int AddFunction(int i) +{ + return i + 1; +} + +class PTest1 +{ +public: + int Add(int i) + { + return i + 2; + } +}; +class PTest2 +{ +public: + int Sub(int i) + { + return i - 1; + } +}; +int PtrFunction(const ::sofa::pbrpc::shared_ptr& p1, const ::sofa::pbrpc::shared_ptr& p2, int i) +{ + i = p1->Add(i); + i = p2->Sub(i); + return i; +} + +TEST_F(Performance, CxxFunction) +{ + for (int i = 0; i < kLoopCount; ++i) + { + NullFunction(); + } +} + +TEST_F(Performance, Closure_null) +{ + for (int i = 0; i < kLoopCount; ++i) + { + ExtClosure* closure = NewExtClosure(NullFunction); + closure->Run(); + } +} + +TEST_F(Performance, Bind_null) +{ + for (int i = 0; i < kLoopCount; ++i) + { + boost::function func = boost::bind(NullFunction); + func(); + } +} + +TEST_F(Performance, Closure_add) +{ + for (int i = 0; i < kLoopCount;) + { + ExtClosure* closure = NewExtClosure(AddFunction, i); + i = closure->Run(); + } +} + +TEST_F(Performance, Bind_add) +{ + for (int i = 0; i < kLoopCount;) + { + boost::function func = boost::bind(AddFunction, i); + i = func(); + } +} + +TEST_F(Performance, Closure_add_with_pointer) +{ + ::sofa::pbrpc::shared_ptr p1(new PTest1()); + ::sofa::pbrpc::shared_ptr p2(new PTest2()); + for (int i = 0; i < kLoopCount;) + { + ExtClosure* closure = NewExtClosure(PtrFunction, p1, p2); + i = closure->Run(i); + } +} + +TEST_F(Performance, Bind_add_with_pointer) +{ + ::sofa::pbrpc::shared_ptr p1(new PTest1()); + ::sofa::pbrpc::shared_ptr p2(new PTest2()); + for (int i = 0; i < kLoopCount;) + { + boost::function func = boost::bind(PtrFunction, p1, p2, _1); + i = func(i); + } +} + +TEST_F(Performance, PermantClosure) +{ + ExtClosure* closure = NewPermanentExtClosure(&NullFunction); + for (int i = 0; i < kLoopCount; ++i) + { + closure->Run(); + } +} + +TEST_F(Performance, StdFunction) +{ + std::tr1::function function = NullFunction; + for (int i = 0; i < kLoopCount; ++i) + { + function(); + } +} + +TEST_F(Performance, OnceStdFunction) +{ + for (int i = 0; i < kLoopCount; ++i) + { + std::tr1::function function = NullFunction; + function(); + } +} +#endif + +class ClosureInheritTest : public testing::Test +{ +public: + int Foo() { return 42; } +}; + +TEST_F(ClosureInheritTest, Test) +{ + ExtClosure* closure = NewExtClosure(this, &ClosureInheritTest::Foo); + EXPECT_EQ(42, closure->Run()); +} + +void RefTest(int& a, const int& b) +{ + printf("a = %d, b = %d\n", a, b); + a = b; +} + +TEST(ExtClosure, Reference) +{ + ExtClosure* c1 = NewExtClosure(&RefTest); + int a, b = 2; + c1->Run(a, b); + printf("a = %d, b = %d\n", a, b); +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/unit-test/test_thread_group.cc b/unit-test/test_thread_group.cc new file mode 100644 index 0000000..a1f4f34 --- /dev/null +++ b/unit-test/test_thread_group.cc @@ -0,0 +1,51 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include +#include +#include + +class ThreadGroupTest: public ::testing::Test +{ +protected: + ThreadGroupTest() {} + virtual ~ThreadGroupTest() {} + virtual void SetUp() { + // Called before every TEST_F(ThreadGroupTest, *) + } + virtual void TearDown() { + // Called after every TEST_F(ThreadGroupTest, *) + } +}; + +static void test_1_function(bool* called) +{ + *called = true; +} + +TEST_F(ThreadGroupTest, test_1) +{ + sofa::pbrpc::ThreadGroup* thread_group = new sofa::pbrpc::ThreadGroup(4); + + bool dispatch_called = false; + thread_group->dispatch(sofa::pbrpc::NewClosure(&test_1_function, &dispatch_called)); + + bool post_called = false; + thread_group->post(sofa::pbrpc::NewClosure(&test_1_function, &post_called)); + + delete thread_group; + + ASSERT_TRUE(dispatch_called); + ASSERT_TRUE(post_called); +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/unit-test/test_timeout_manager.cc b/unit-test/test_timeout_manager.cc new file mode 100644 index 0000000..3a5be6e --- /dev/null +++ b/unit-test/test_timeout_manager.cc @@ -0,0 +1,100 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include +#include +#include + +using namespace ::sofa::pbrpc; + +class TimeoutManagerTest: public ::testing::Test +{ +protected: + TimeoutManagerTest() {} + virtual ~TimeoutManagerTest() {} + virtual void SetUp() { + // Called before every TEST_F(TimeoutManagerTest, *) + } + virtual void TearDown() { + // Called after every TEST_F(TimeoutManagerTest, *) + } +}; + +typedef std::pair Event; +typedef std::vector EventVec; + +static void SimpleCallback(EventVec* events, + TimeoutManager::Id id, TimeoutManager::Type type) +{ + events->push_back(std::make_pair(id, type)); +} +TEST_F(TimeoutManagerTest, Simple) +{ + TimeoutManager q; + EventVec events; + + ASSERT_EQ(1u, q.add(100, NewExtClosure(&SimpleCallback, &events))); + ASSERT_EQ(2u, q.add(200, NewExtClosure(&SimpleCallback, &events))); + ASSERT_EQ(3u, q.add_repeating(200, NewPermanentExtClosure(&SimpleCallback, &events))); + + usleep(500000); + + ASSERT_EQ(4u, events.size()); + ASSERT_EQ(Event(1u, TimeoutManager::TIMEOUTED), events[0]); + ASSERT_EQ(Event(2u, TimeoutManager::TIMEOUTED), events[1]); + ASSERT_EQ(Event(3u, TimeoutManager::TIMEOUTED), events[2]); + ASSERT_EQ(Event(3u, TimeoutManager::TIMEOUTED), events[3]); + + q.clear(); + + ASSERT_EQ(5u, events.size()); + ASSERT_EQ(Event(1u, TimeoutManager::TIMEOUTED), events[0]); + ASSERT_EQ(Event(2u, TimeoutManager::TIMEOUTED), events[1]); + ASSERT_EQ(Event(3u, TimeoutManager::TIMEOUTED), events[2]); + ASSERT_EQ(Event(3u, TimeoutManager::TIMEOUTED), events[3]); + ASSERT_EQ(Event(3u, TimeoutManager::CLEARED), events[4]); +} + +static void EraseCallback(TimeoutManager* q, EventVec* events, + TimeoutManager::Id id, TimeoutManager::Type type) +{ + events->push_back(std::make_pair(id, type)); + if (id == 2) { + q->erase(1); + } +} +TEST(TimeoutManager, Erase) +{ + TimeoutManager q; + EventVec events; + + ASSERT_EQ(1u, q.add_repeating(200, NewPermanentExtClosure(&EraseCallback, &q, &events))); + ASSERT_EQ(2u, q.add(500, NewExtClosure(&EraseCallback, &q, &events))); + + usleep(600000); + + ASSERT_EQ(4u, events.size()); + ASSERT_EQ(Event(1u, TimeoutManager::TIMEOUTED), events[0]); + ASSERT_EQ(Event(1u, TimeoutManager::TIMEOUTED), events[1]); + ASSERT_EQ(Event(2u, TimeoutManager::TIMEOUTED), events[2]); + ASSERT_EQ(Event(1u, TimeoutManager::ERASED), events[3]); + + q.clear(); + + ASSERT_EQ(4u, events.size()); + ASSERT_EQ(Event(1u, TimeoutManager::TIMEOUTED), events[0]); + ASSERT_EQ(Event(1u, TimeoutManager::TIMEOUTED), events[1]); + ASSERT_EQ(Event(2u, TimeoutManager::TIMEOUTED), events[2]); + ASSERT_EQ(Event(1u, TimeoutManager::ERASED), events[3]); +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/unit-test/test_timeout_queue.cc b/unit-test/test_timeout_queue.cc new file mode 100644 index 0000000..d767c9a --- /dev/null +++ b/unit-test/test_timeout_queue.cc @@ -0,0 +1,142 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#include +#include +#include + +using namespace ::sofa::pbrpc; + +class TimeoutQueueTest: public ::testing::Test +{ +protected: + TimeoutQueueTest() {} + virtual ~TimeoutQueueTest() {} + virtual void SetUp() { + // Called before every TEST_F(TimeoutQueueTest, *) + } + virtual void TearDown() { + // Called after every TEST_F(TimeoutQueueTest, *) + } +}; + +typedef std::vector EventVec; + +static void SimpleCallback( + EventVec* events, uint64 id, int64 /*now*/) +{ + events->push_back(id); +} +TEST_F(TimeoutQueueTest, Simple) +{ + EventVec events; + TimeoutQueue q; + + ASSERT_EQ(1u, q.add(0, 10, NewExtClosure( + &SimpleCallback, &events))); + ASSERT_EQ(2u, q.add(0, 11, NewExtClosure( + &SimpleCallback, &events))); + ASSERT_EQ(3u, q.add_repeating(0, 9, NewPermanentExtClosure( + &SimpleCallback, &events))); + + ASSERT_TRUE(events.empty()); + ASSERT_EQ(21, q.run_once(12)); // now+9 + + ASSERT_EQ(3u, events.size()); + ASSERT_EQ(3u, events[0]); + ASSERT_EQ(1u, events[1]); + ASSERT_EQ(2u, events[2]); + + events.clear(); + ASSERT_EQ(49, q.run_once(40)); + ASSERT_EQ(1u, events.size()); + ASSERT_EQ(3u, events[0]); +} + +static void EraseCallback( + TimeoutQueue* q, EventVec* events, uint64 id, int64 /*now*/) +{ + events->push_back(id); + if (id == 2) { + q->erase(1); + } +} +TEST(TimeoutQueue, Erase) +{ + TimeoutQueue q; + EventVec events; + + ASSERT_EQ(1u, q.add_repeating(0, 10, NewPermanentExtClosure( + &EraseCallback, &q, &events))); + ASSERT_EQ(2u, q.add(0, 35, NewExtClosure( + &EraseCallback, &q, &events))); + + int64 now = 0; + while (now < kint64max) { + now = q.run_once(now); + } + + ASSERT_EQ(4u, events.size()); + ASSERT_EQ(1u, events[0]); + ASSERT_EQ(1u, events[1]); + ASSERT_EQ(1u, events[2]); + ASSERT_EQ(2u, events[3]); +} + +static void RunOnceRepeatingCallback( + TimeoutQueue* q, int* count, uint64 id, int64 /*now*/) +{ + if (++(*count) == 100) { + ASSERT_TRUE(q->erase(id)); + } +} +TEST(TimeoutQueue, RunOnceRepeating) +{ + int count = 0; + TimeoutQueue q; + + ASSERT_EQ(1u, q.add_repeating(0, 0, NewPermanentExtClosure( + &RunOnceRepeatingCallback, &q, &count))); + + ASSERT_EQ(0, q.run_once(0)); + ASSERT_EQ(1, count); + ASSERT_EQ(0, q.run_once(0)); + ASSERT_EQ(2, count); + ASSERT_EQ(kint64max, q.run_loop(0)); + ASSERT_EQ(100, count); +} + +static void RunOnceRescheduleCallback( + TimeoutQueue* q, int* count, uint64 id, int64 now) +{ + if (++(*count) < 100) { + ASSERT_LT(id, q->add(now, 0, NewExtClosure( + &RunOnceRescheduleCallback, q, count))); + } +} +TEST(TimeoutQueue, RunOnceReschedule) +{ + int count = 0; + TimeoutQueue q; + + ASSERT_EQ(1u, q.add(0, 0, NewExtClosure( + &RunOnceRescheduleCallback, &q, &count))); + + ASSERT_EQ(0, q.run_once(0)); + ASSERT_EQ(1, count); + ASSERT_EQ(0, q.run_once(0)); + ASSERT_EQ(2, count); + ASSERT_EQ(kint64max, q.run_loop(0)); + ASSERT_EQ(100, count); +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +/* vim: set ts=4 sw=4 sts=4 tw=100 */ diff --git a/unit-test/test_tran_buf_pool.cc b/unit-test/test_tran_buf_pool.cc new file mode 100644 index 0000000..8eba688 --- /dev/null +++ b/unit-test/test_tran_buf_pool.cc @@ -0,0 +1,42 @@ +// Copyright (c) 2014 Baidu.com, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Author: qinzuoyan01@baidu.com (Qin Zuoyan) + +#define SOFA_PBRPC_TRAN_BUF_BLOCK_SIZE 1024 + +#include +#include + +using namespace sofa::pbrpc; + +class TranBufPoolTest : public ::testing::Test {}; + +TEST_F(TranBufPoolTest, malloc_free_test) +{ + ASSERT_EQ(1024, TranBufPool::block_size()); + + void* data = TranBufPool::malloc(); + ASSERT_TRUE(NULL != data); + TranBufPool::free(data); +} + +TEST_F(TranBufPoolTest, add_ref_test) +{ + ASSERT_EQ(1024, TranBufPool::block_size()); + + void* data = TranBufPool::malloc(); + ASSERT_TRUE(NULL != data); + TranBufPool::add_ref(data); + TranBufPool::free(data); + TranBufPool::free(data); +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +/* vim: set ts=4 sw=4 sts=4 tw=100 */