Moving from govendor to dep, updated dependencies (#48)
* Moving from govendor to dep. * Making the pull request template more friendly. * Fixing akward space in PR template. * goimports run on whole project using ` goimports -w $(find . -type f -name '*.go' -not -path "./vendor/*" -not -path "./gen-go/*")` source of command: https://gist.github.com/bgentry/fd1ffef7dbde01857f66
This commit is contained in:
parent
9631aa3aab
commit
8d445c1c77
2186 changed files with 400410 additions and 352 deletions
25
vendor/git.apache.org/thrift.git/lib/cpp/3rdparty.props
generated
vendored
Normal file
25
vendor/git.apache.org/thrift.git/lib/cpp/3rdparty.props
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Label="PropertySheets" />
|
||||
<PropertyGroup Label="UserMacros">
|
||||
<BOOST_ROOT>$(THIRD_PARTY)\boost\boost_1_47_0</BOOST_ROOT>
|
||||
<OPENSSL_ROOT_DIR>$(THIRD_PARTY)\openssl\OpenSSL-Win32</OPENSSL_ROOT_DIR>
|
||||
<LIBEVENT_ROOT>$(THIRD_PARTY)\libevent-2.0.21-stable</LIBEVENT_ROOT>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup />
|
||||
<ItemGroup>
|
||||
<BuildMacro Include="BOOST_ROOT">
|
||||
<Value>$(BOOST_ROOT)</Value>
|
||||
<EnvironmentVariable>true</EnvironmentVariable>
|
||||
</BuildMacro>
|
||||
<BuildMacro Include="OPENSSL_ROOT_DIR">
|
||||
<Value>$(OPENSSL_ROOT_DIR)</Value>
|
||||
<EnvironmentVariable>true</EnvironmentVariable>
|
||||
</BuildMacro>
|
||||
<BuildMacro Include="LIBEVENT_ROOT">
|
||||
<Value>$(LIBEVENT_ROOT)</Value>
|
||||
<EnvironmentVariable>true</EnvironmentVariable>
|
||||
</BuildMacro>
|
||||
</ItemGroup>
|
||||
</Project>
|
217
vendor/git.apache.org/thrift.git/lib/cpp/CMakeLists.txt
generated
vendored
Executable file
217
vendor/git.apache.org/thrift.git/lib/cpp/CMakeLists.txt
generated
vendored
Executable file
|
@ -0,0 +1,217 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
include_directories(SYSTEM "${Boost_INCLUDE_DIRS}")
|
||||
include_directories(src)
|
||||
|
||||
# SYSLIBS contains libraries that need to be linked to all lib targets
|
||||
set(SYSLIBS "")
|
||||
|
||||
# Create the thrift C++ library
|
||||
set( thriftcpp_SOURCES
|
||||
src/thrift/TApplicationException.cpp
|
||||
src/thrift/TOutput.cpp
|
||||
src/thrift/async/TAsyncChannel.cpp
|
||||
src/thrift/async/TConcurrentClientSyncInfo.h
|
||||
src/thrift/async/TConcurrentClientSyncInfo.cpp
|
||||
src/thrift/concurrency/ThreadManager.cpp
|
||||
src/thrift/concurrency/TimerManager.cpp
|
||||
src/thrift/concurrency/Util.cpp
|
||||
src/thrift/processor/PeekProcessor.cpp
|
||||
src/thrift/protocol/TBase64Utils.cpp
|
||||
src/thrift/protocol/TDebugProtocol.cpp
|
||||
src/thrift/protocol/TJSONProtocol.cpp
|
||||
src/thrift/protocol/TMultiplexedProtocol.cpp
|
||||
src/thrift/protocol/TProtocol.cpp
|
||||
src/thrift/transport/TTransportException.cpp
|
||||
src/thrift/transport/TFDTransport.cpp
|
||||
src/thrift/transport/TSimpleFileTransport.cpp
|
||||
src/thrift/transport/THttpTransport.cpp
|
||||
src/thrift/transport/THttpClient.cpp
|
||||
src/thrift/transport/THttpServer.cpp
|
||||
src/thrift/transport/TSocket.cpp
|
||||
src/thrift/transport/TSocketPool.cpp
|
||||
src/thrift/transport/TServerSocket.cpp
|
||||
src/thrift/transport/TTransportUtils.cpp
|
||||
src/thrift/transport/TBufferTransports.cpp
|
||||
src/thrift/server/TConnectedClient.cpp
|
||||
src/thrift/server/TServerFramework.cpp
|
||||
src/thrift/server/TSimpleServer.cpp
|
||||
src/thrift/server/TThreadPoolServer.cpp
|
||||
src/thrift/server/TThreadedServer.cpp
|
||||
)
|
||||
|
||||
# This files don't work on Windows CE as there is no pipe support
|
||||
# TODO: These files won't work with UNICODE support on windows. If fixed this can be re-added.
|
||||
if (NOT WINCE)
|
||||
list(APPEND thriftcpp_SOURCES
|
||||
src/thrift/transport/TPipe.cpp
|
||||
src/thrift/transport/TPipeServer.cpp
|
||||
src/thrift/transport/TFileTransport.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
if (WIN32)
|
||||
list(APPEND thriftcpp_SOURCES
|
||||
src/thrift/windows/TWinsockSingleton.cpp
|
||||
src/thrift/windows/SocketPair.cpp
|
||||
src/thrift/windows/GetTimeOfDay.cpp
|
||||
src/thrift/windows/WinFcntl.cpp
|
||||
)
|
||||
if(NOT WINCE)
|
||||
# This file uses pipes so it currently won't work on Windows CE
|
||||
list(APPEND thriftcpp_SOURCES
|
||||
src/thrift/windows/OverlappedSubmissionThread.cpp
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
# These files evaluate to nothing on Windows, so omit them from the
|
||||
# Windows build
|
||||
list(APPEND thriftcpp_SOURCES
|
||||
src/thrift/VirtualProfiling.cpp
|
||||
src/thrift/server/TServer.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
# If OpenSSL is not found just ignore the OpenSSL stuff
|
||||
find_package(OpenSSL)
|
||||
if(OPENSSL_FOUND AND WITH_OPENSSL)
|
||||
list( APPEND thriftcpp_SOURCES
|
||||
src/thrift/transport/TSSLSocket.cpp
|
||||
src/thrift/transport/TSSLServerSocket.cpp
|
||||
)
|
||||
include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}")
|
||||
list(APPEND SYSLIBS "${OPENSSL_LIBRARIES}")
|
||||
endif()
|
||||
|
||||
# WITH_*THREADS selects which threading library to use
|
||||
if(WITH_BOOSTTHREADS)
|
||||
set( thriftcpp_threads_SOURCES
|
||||
src/thrift/concurrency/BoostThreadFactory.cpp
|
||||
src/thrift/concurrency/BoostMonitor.cpp
|
||||
src/thrift/concurrency/BoostMutex.cpp
|
||||
)
|
||||
list(APPEND SYSLIBS "${Boost_LIBRARIES}")
|
||||
elseif(UNIX AND NOT WITH_STDTHREADS)
|
||||
if(ANDROID)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
|
||||
else()
|
||||
list(APPEND SYSLIBS pthread)
|
||||
endif()
|
||||
set( thriftcpp_threads_SOURCES
|
||||
src/thrift/concurrency/PosixThreadFactory.cpp
|
||||
src/thrift/concurrency/Mutex.cpp
|
||||
src/thrift/concurrency/Monitor.cpp
|
||||
)
|
||||
else()
|
||||
if(UNIX)
|
||||
if(ANDROID)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
|
||||
else()
|
||||
list(APPEND SYSLIBS pthread)
|
||||
endif()
|
||||
endif()
|
||||
set( thriftcpp_threads_SOURCES
|
||||
src/thrift/concurrency/StdThreadFactory.cpp
|
||||
src/thrift/concurrency/StdMutex.cpp
|
||||
src/thrift/concurrency/StdMonitor.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
# Thrift non blocking server
|
||||
set( thriftcppnb_SOURCES
|
||||
src/thrift/server/TNonblockingServer.cpp
|
||||
src/thrift/async/TAsyncProtocolProcessor.cpp
|
||||
src/thrift/async/TEvhttpServer.cpp
|
||||
src/thrift/async/TEvhttpClientChannel.cpp
|
||||
)
|
||||
|
||||
# Thrift zlib server
|
||||
set( thriftcppz_SOURCES
|
||||
src/thrift/transport/TZlibTransport.cpp
|
||||
src/thrift/protocol/THeaderProtocol.cpp
|
||||
src/thrift/transport/THeaderTransport.cpp
|
||||
src/thrift/protocol/THeaderProtocol.cpp
|
||||
src/thrift/transport/THeaderTransport.cpp
|
||||
)
|
||||
|
||||
# Thrift Qt4 server
|
||||
set( thriftcppqt_SOURCES
|
||||
src/thrift/qt/TQIODeviceTransport.cpp
|
||||
src/thrift/qt/TQTcpServer.cpp
|
||||
)
|
||||
|
||||
# Contains the thrift specific ADD_LIBRARY_THRIFT and TARGET_LINK_LIBRARIES_THRIFT
|
||||
include(ThriftMacros)
|
||||
|
||||
ADD_LIBRARY_THRIFT(thrift ${thriftcpp_SOURCES} ${thriftcpp_threads_SOURCES})
|
||||
if(WIN32)
|
||||
TARGET_LINK_LIBRARIES_THRIFT(thrift ${SYSLIBS} ws2_32)
|
||||
else()
|
||||
TARGET_LINK_LIBRARIES_THRIFT(thrift ${SYSLIBS})
|
||||
endif()
|
||||
|
||||
if(WITH_LIBEVENT)
|
||||
find_package(Libevent REQUIRED) # Libevent comes with CMake support form upstream
|
||||
include_directories(SYSTEM ${LIBEVENT_INCLUDE_DIRS})
|
||||
|
||||
ADD_LIBRARY_THRIFT(thriftnb ${thriftcppnb_SOURCES})
|
||||
TARGET_LINK_LIBRARIES_THRIFT(thriftnb ${SYSLIBS} ${LIBEVENT_LIBRARIES})
|
||||
TARGET_LINK_LIBRARIES_THRIFT_AGAINST_THRIFT_LIBRARY(thriftnb thrift)
|
||||
endif()
|
||||
|
||||
if(WITH_ZLIB)
|
||||
find_package(ZLIB REQUIRED)
|
||||
include_directories(SYSTEM ${ZLIB_INCLUDE_DIRS})
|
||||
|
||||
ADD_LIBRARY_THRIFT(thriftz ${thriftcppz_SOURCES})
|
||||
TARGET_LINK_LIBRARIES_THRIFT(thriftz ${SYSLIBS} ${ZLIB_LIBRARIES})
|
||||
TARGET_LINK_LIBRARIES_THRIFT_AGAINST_THRIFT_LIBRARY(thriftz thrift)
|
||||
endif()
|
||||
|
||||
if(WITH_QT4)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
find_package(Qt4 REQUIRED COMPONENTS QtCore QtNetwork)
|
||||
ADD_LIBRARY_THRIFT(thriftqt ${thriftcppqt_SOURCES})
|
||||
TARGET_LINK_LIBRARIES_THRIFT(thriftqt ${SYSLIBS} Qt4::QtCore Qt4::QtNetwork)
|
||||
TARGET_LINK_LIBRARIES_THRIFT_AGAINST_THRIFT_LIBRARY(thriftqt thrift)
|
||||
endif()
|
||||
|
||||
if(WITH_QT5)
|
||||
# Qt5 has its own directory to avoid conflict with Qt4 caused by CMAKE_AUTOMOC
|
||||
add_subdirectory(src/thrift/qt)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
add_definitions("-DUNICODE -D_UNICODE")
|
||||
endif()
|
||||
|
||||
add_definitions("-D__STDC_LIMIT_MACROS")
|
||||
|
||||
# Install the headers
|
||||
install(DIRECTORY "src/thrift" DESTINATION "${INCLUDE_INSTALL_DIR}"
|
||||
FILES_MATCHING PATTERN "*.h" PATTERN "*.tcc")
|
||||
# Copy config.h file
|
||||
install(DIRECTORY "${CMAKE_BINARY_DIR}/thrift" DESTINATION "${INCLUDE_INSTALL_DIR}"
|
||||
FILES_MATCHING PATTERN "*.h")
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_subdirectory(test)
|
||||
endif()
|
287
vendor/git.apache.org/thrift.git/lib/cpp/Makefile.am
generated
vendored
Executable file
287
vendor/git.apache.org/thrift.git/lib/cpp/Makefile.am
generated
vendored
Executable file
|
@ -0,0 +1,287 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
AUTOMAKE_OPTIONS = subdir-objects
|
||||
|
||||
moc_%.cpp: %.h
|
||||
$(QT_MOC) $(QT_CFLAGS) $< -o $@
|
||||
|
||||
moc__%.cpp: %.h
|
||||
$(QT5_MOC) $(QT5_CFLAGS) $< -o $@
|
||||
|
||||
SUBDIRS = .
|
||||
|
||||
if WITH_TESTS
|
||||
# This file is needed by compiler with plugin, while test/Makefile.am needs compiler
|
||||
# So test directory is directly picked by top level Makefile.am for plugin build
|
||||
if !WITH_PLUGIN
|
||||
SUBDIRS += test
|
||||
endif
|
||||
endif
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
|
||||
lib_LTLIBRARIES = libthrift.la
|
||||
pkgconfig_DATA = thrift.pc
|
||||
libthrift_la_LDFLAGS = -release $(VERSION)
|
||||
libthrift_la_LIBADD = $(BOOST_LDFLAGS) $(OPENSSL_LDFLAGS) $(OPENSSL_LIBS)
|
||||
|
||||
## We only build the extra libraries if we have the dependencies,
|
||||
## but we install all of the headers unconditionally.
|
||||
if AMX_HAVE_LIBEVENT
|
||||
lib_LTLIBRARIES += libthriftnb.la
|
||||
pkgconfig_DATA += thrift-nb.pc
|
||||
endif
|
||||
if AMX_HAVE_ZLIB
|
||||
lib_LTLIBRARIES += libthriftz.la
|
||||
pkgconfig_DATA += thrift-z.pc
|
||||
endif
|
||||
if AMX_HAVE_QT
|
||||
lib_LTLIBRARIES += libthriftqt.la
|
||||
pkgconfig_DATA += thrift-qt.pc
|
||||
endif
|
||||
if AMX_HAVE_QT5
|
||||
lib_LTLIBRARIES += libthriftqt5.la
|
||||
pkgconfig_DATA += thrift-qt5.pc
|
||||
endif
|
||||
|
||||
AM_CXXFLAGS = -Wall -Wextra -pedantic
|
||||
AM_CPPFLAGS = $(BOOST_CPPFLAGS) $(OPENSSL_INCLUDES) -I$(srcdir)/src -D__STDC_LIMIT_MACROS
|
||||
|
||||
# Define the source files for the module
|
||||
|
||||
libthrift_la_SOURCES = src/thrift/TApplicationException.cpp \
|
||||
src/thrift/TOutput.cpp \
|
||||
src/thrift/VirtualProfiling.cpp \
|
||||
src/thrift/async/TAsyncChannel.cpp \
|
||||
src/thrift/async/TConcurrentClientSyncInfo.cpp \
|
||||
src/thrift/concurrency/ThreadManager.cpp \
|
||||
src/thrift/concurrency/TimerManager.cpp \
|
||||
src/thrift/concurrency/Util.cpp \
|
||||
src/thrift/processor/PeekProcessor.cpp \
|
||||
src/thrift/protocol/TDebugProtocol.cpp \
|
||||
src/thrift/protocol/TJSONProtocol.cpp \
|
||||
src/thrift/protocol/TBase64Utils.cpp \
|
||||
src/thrift/protocol/TMultiplexedProtocol.cpp \
|
||||
src/thrift/protocol/TProtocol.cpp \
|
||||
src/thrift/transport/TTransportException.cpp \
|
||||
src/thrift/transport/TFDTransport.cpp \
|
||||
src/thrift/transport/TFileTransport.cpp \
|
||||
src/thrift/transport/TSimpleFileTransport.cpp \
|
||||
src/thrift/transport/THttpTransport.cpp \
|
||||
src/thrift/transport/THttpClient.cpp \
|
||||
src/thrift/transport/THttpServer.cpp \
|
||||
src/thrift/transport/TSocket.cpp \
|
||||
src/thrift/transport/TPipe.cpp \
|
||||
src/thrift/transport/TPipeServer.cpp \
|
||||
src/thrift/transport/TSSLSocket.cpp \
|
||||
src/thrift/transport/TSocketPool.cpp \
|
||||
src/thrift/transport/TServerSocket.cpp \
|
||||
src/thrift/transport/TSSLServerSocket.cpp \
|
||||
src/thrift/transport/TTransportUtils.cpp \
|
||||
src/thrift/transport/TBufferTransports.cpp \
|
||||
src/thrift/server/TConnectedClient.cpp \
|
||||
src/thrift/server/TServer.cpp \
|
||||
src/thrift/server/TServerFramework.cpp \
|
||||
src/thrift/server/TSimpleServer.cpp \
|
||||
src/thrift/server/TThreadPoolServer.cpp \
|
||||
src/thrift/server/TThreadedServer.cpp
|
||||
|
||||
if WITH_BOOSTTHREADS
|
||||
libthrift_la_SOURCES += src/thrift/concurrency/BoostThreadFactory.cpp \
|
||||
src/thrift/concurrency/BoostMonitor.cpp \
|
||||
src/thrift/concurrency/BoostMutex.cpp
|
||||
else
|
||||
libthrift_la_SOURCES += src/thrift/concurrency/Mutex.cpp \
|
||||
src/thrift/concurrency/Monitor.cpp \
|
||||
src/thrift/concurrency/PosixThreadFactory.cpp
|
||||
endif
|
||||
|
||||
libthriftnb_la_SOURCES = src/thrift/server/TNonblockingServer.cpp \
|
||||
src/thrift/async/TAsyncProtocolProcessor.cpp \
|
||||
src/thrift/async/TEvhttpServer.cpp \
|
||||
src/thrift/async/TEvhttpClientChannel.cpp
|
||||
|
||||
libthriftz_la_SOURCES = src/thrift/transport/TZlibTransport.cpp \
|
||||
src/thrift/transport/THeaderTransport.cpp \
|
||||
src/thrift/protocol/THeaderProtocol.cpp
|
||||
|
||||
|
||||
libthriftqt_la_MOC = src/thrift/qt/moc_TQTcpServer.cpp
|
||||
nodist_libthriftqt_la_SOURCES = $(libthriftqt_la_MOC)
|
||||
libthriftqt_la_SOURCES = src/thrift/qt/TQIODeviceTransport.cpp \
|
||||
src/thrift/qt/TQTcpServer.cpp
|
||||
CLEANFILES = $(libthriftqt_la_MOC)
|
||||
|
||||
libthriftqt5_la_MOC = src/thrift/qt/moc__TQTcpServer.cpp
|
||||
nodist_libthriftqt5_la_SOURCES = $(libthriftqt5_la_MOC)
|
||||
libthriftqt5_la_SOURCES = src/thrift/qt/TQIODeviceTransport.cpp \
|
||||
src/thrift/qt/TQTcpServer.cpp
|
||||
CLEANFILES += $(libthriftqt5_la_MOC)
|
||||
|
||||
# Flags for the various libraries
|
||||
libthriftnb_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBEVENT_CPPFLAGS)
|
||||
libthriftz_la_CPPFLAGS = $(AM_CPPFLAGS) $(ZLIB_CPPFLAGS)
|
||||
libthriftqt_la_CPPFLAGS = $(AM_CPPFLAGS) $(QT_CFLAGS)
|
||||
libthriftqt5_la_CPPFLAGS = $(AM_CPPFLAGS) $(QT5_CFLAGS)
|
||||
if QT5_REDUCE_RELOCATIONS
|
||||
libthriftqt5_la_CPPFLAGS += -fPIC
|
||||
endif
|
||||
libthriftnb_la_CXXFLAGS = $(AM_CXXFLAGS)
|
||||
libthriftz_la_CXXFLAGS = $(AM_CXXFLAGS)
|
||||
libthriftqt_la_CXXFLAGS = $(AM_CXXFLAGS)
|
||||
libthriftqt5_la_CXXFLAGS = $(AM_CXXFLAGS)
|
||||
libthriftnb_la_LDFLAGS = -release $(VERSION) $(BOOST_LDFLAGS)
|
||||
libthriftz_la_LDFLAGS = -release $(VERSION) $(BOOST_LDFLAGS)
|
||||
libthriftqt_la_LDFLAGS = -release $(VERSION) $(BOOST_LDFLAGS) $(QT_LIBS)
|
||||
libthriftqt5_la_LDFLAGS = -release $(VERSION) $(BOOST_LDFLAGS) $(QT5_LIBS)
|
||||
|
||||
include_thriftdir = $(includedir)/thrift
|
||||
include_thrift_HEADERS = \
|
||||
$(top_builddir)/config.h \
|
||||
src/thrift/thrift-config.h \
|
||||
src/thrift/TDispatchProcessor.h \
|
||||
src/thrift/Thrift.h \
|
||||
src/thrift/TOutput.h \
|
||||
src/thrift/TProcessor.h \
|
||||
src/thrift/TApplicationException.h \
|
||||
src/thrift/TLogging.h \
|
||||
src/thrift/cxxfunctional.h \
|
||||
src/thrift/TToString.h \
|
||||
src/thrift/TBase.h
|
||||
|
||||
include_concurrencydir = $(include_thriftdir)/concurrency
|
||||
include_concurrency_HEADERS = \
|
||||
src/thrift/concurrency/BoostThreadFactory.h \
|
||||
src/thrift/concurrency/Exception.h \
|
||||
src/thrift/concurrency/Mutex.h \
|
||||
src/thrift/concurrency/Monitor.h \
|
||||
src/thrift/concurrency/PlatformThreadFactory.h \
|
||||
src/thrift/concurrency/PosixThreadFactory.h \
|
||||
src/thrift/concurrency/StdMonitor.cpp \
|
||||
src/thrift/concurrency/StdMutex.cpp \
|
||||
src/thrift/concurrency/StdThreadFactory.cpp \
|
||||
src/thrift/concurrency/StdThreadFactory.h \
|
||||
src/thrift/concurrency/Thread.h \
|
||||
src/thrift/concurrency/ThreadManager.h \
|
||||
src/thrift/concurrency/TimerManager.h \
|
||||
src/thrift/concurrency/FunctionRunner.h \
|
||||
src/thrift/concurrency/Util.h
|
||||
|
||||
include_protocoldir = $(include_thriftdir)/protocol
|
||||
include_protocol_HEADERS = \
|
||||
src/thrift/protocol/TBinaryProtocol.h \
|
||||
src/thrift/protocol/TBinaryProtocol.tcc \
|
||||
src/thrift/protocol/TCompactProtocol.h \
|
||||
src/thrift/protocol/TCompactProtocol.tcc \
|
||||
src/thrift/protocol/TDebugProtocol.h \
|
||||
src/thrift/protocol/THeaderProtocol.h \
|
||||
src/thrift/protocol/TBase64Utils.h \
|
||||
src/thrift/protocol/TJSONProtocol.h \
|
||||
src/thrift/protocol/TMultiplexedProtocol.h \
|
||||
src/thrift/protocol/TProtocolDecorator.h \
|
||||
src/thrift/protocol/TProtocolTap.h \
|
||||
src/thrift/protocol/TProtocolTypes.h \
|
||||
src/thrift/protocol/TProtocolException.h \
|
||||
src/thrift/protocol/TVirtualProtocol.h \
|
||||
src/thrift/protocol/TProtocol.h
|
||||
|
||||
include_transportdir = $(include_thriftdir)/transport
|
||||
include_transport_HEADERS = \
|
||||
src/thrift/transport/PlatformSocket.h \
|
||||
src/thrift/transport/TFDTransport.h \
|
||||
src/thrift/transport/TFileTransport.h \
|
||||
src/thrift/transport/THeaderTransport.h \
|
||||
src/thrift/transport/TSimpleFileTransport.h \
|
||||
src/thrift/transport/TServerSocket.h \
|
||||
src/thrift/transport/TSSLServerSocket.h \
|
||||
src/thrift/transport/TServerTransport.h \
|
||||
src/thrift/transport/THttpTransport.h \
|
||||
src/thrift/transport/THttpClient.h \
|
||||
src/thrift/transport/THttpServer.h \
|
||||
src/thrift/transport/TSocket.h \
|
||||
src/thrift/transport/TPipe.h \
|
||||
src/thrift/transport/TPipeServer.h \
|
||||
src/thrift/transport/TSSLSocket.h \
|
||||
src/thrift/transport/TSocketPool.h \
|
||||
src/thrift/transport/TVirtualTransport.h \
|
||||
src/thrift/transport/TTransport.h \
|
||||
src/thrift/transport/TTransportException.h \
|
||||
src/thrift/transport/TTransportUtils.h \
|
||||
src/thrift/transport/TBufferTransports.h \
|
||||
src/thrift/transport/TShortReadTransport.h \
|
||||
src/thrift/transport/TZlibTransport.h
|
||||
|
||||
include_serverdir = $(include_thriftdir)/server
|
||||
include_server_HEADERS = \
|
||||
src/thrift/server/TConnectedClient.h \
|
||||
src/thrift/server/TServer.h \
|
||||
src/thrift/server/TServerFramework.h \
|
||||
src/thrift/server/TSimpleServer.h \
|
||||
src/thrift/server/TThreadPoolServer.h \
|
||||
src/thrift/server/TThreadedServer.h \
|
||||
src/thrift/server/TNonblockingServer.h
|
||||
|
||||
include_processordir = $(include_thriftdir)/processor
|
||||
include_processor_HEADERS = \
|
||||
src/thrift/processor/PeekProcessor.h \
|
||||
src/thrift/processor/StatsProcessor.h \
|
||||
src/thrift/processor/TMultiplexedProcessor.h
|
||||
|
||||
include_asyncdir = $(include_thriftdir)/async
|
||||
include_async_HEADERS = \
|
||||
src/thrift/async/TAsyncChannel.h \
|
||||
src/thrift/async/TAsyncDispatchProcessor.h \
|
||||
src/thrift/async/TAsyncProcessor.h \
|
||||
src/thrift/async/TAsyncBufferProcessor.h \
|
||||
src/thrift/async/TAsyncProtocolProcessor.h \
|
||||
src/thrift/async/TConcurrentClientSyncInfo.h \
|
||||
src/thrift/async/TEvhttpClientChannel.h \
|
||||
src/thrift/async/TEvhttpServer.h
|
||||
|
||||
include_qtdir = $(include_thriftdir)/qt
|
||||
include_qt_HEADERS = \
|
||||
src/thrift/qt/TQIODeviceTransport.h \
|
||||
src/thrift/qt/TQTcpServer.h
|
||||
|
||||
THRIFT = $(top_builddir)/compiler/cpp/thrift
|
||||
|
||||
WINDOWS_DIST = \
|
||||
src/thrift/windows \
|
||||
thrift.sln \
|
||||
libthrift.vcxproj \
|
||||
libthrift.vcxproj.filters \
|
||||
libthriftnb.vcxproj \
|
||||
libthriftnb.vcxproj.filters \
|
||||
3rdparty.props
|
||||
|
||||
EXTRA_DIST = \
|
||||
CMakeLists.txt \
|
||||
coding_standards.md \
|
||||
README.md \
|
||||
thrift-nb.pc.in \
|
||||
thrift.pc.in \
|
||||
thrift-z.pc.in \
|
||||
thrift-qt.pc.in \
|
||||
thrift-qt5.pc.in \
|
||||
src/thrift/qt/CMakeLists.txt \
|
||||
$(WINDOWS_DIST)
|
||||
|
||||
style-local:
|
||||
$(CPPSTYLE_CMD)
|
274
vendor/git.apache.org/thrift.git/lib/cpp/README.md
generated
vendored
Executable file
274
vendor/git.apache.org/thrift.git/lib/cpp/README.md
generated
vendored
Executable file
|
@ -0,0 +1,274 @@
|
|||
Thrift C++ Software Library
|
||||
|
||||
# License
|
||||
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
|
||||
# Using Thrift with C++
|
||||
|
||||
The Thrift C++ libraries are built using the GNU tools. Follow the instructions
|
||||
in the top-level README.md
|
||||
|
||||
In case you do not want to open another README.md file, do this thrift src:
|
||||
|
||||
./bootstrap.sh
|
||||
./configure (--with-boost=/usr/local)
|
||||
make
|
||||
sudo make install
|
||||
|
||||
Thrift is divided into two libraries.
|
||||
|
||||
* libthrift - The core Thrift library contains all the core Thrift code. It requires
|
||||
boost shared pointers, pthreads, and librt.
|
||||
|
||||
* libthriftnb - This library contains the Thrift nonblocking server, which uses libevent.
|
||||
To link this library you will also need to link libevent.
|
||||
|
||||
## Linking Against Thrift
|
||||
|
||||
After you build and install Thrift the libraries are installed to
|
||||
/usr/local/lib by default. Make sure this is in your LDPATH.
|
||||
|
||||
On Linux, the best way to do this is to ensure that /usr/local/lib is in
|
||||
your /etc/ld.so.conf and then run /sbin/ldconfig.
|
||||
|
||||
Depending upon whether you are linking dynamically or statically and how
|
||||
your build environment it set up, you may need to include additional
|
||||
libraries when linking against thrift, such as librt and/or libpthread. If
|
||||
you are using libthriftnb you will also need libevent.
|
||||
|
||||
## Dependencies
|
||||
|
||||
boost shared pointers
|
||||
http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
|
||||
libevent (for libthriftnb only)
|
||||
http://monkey.org/~provos/libevent/
|
||||
|
||||
# Using Thrift with C++ on Windows
|
||||
|
||||
You need to define an environment variables for 3rd party components separately:
|
||||
|
||||
BOOST_ROOT : For boost, e.g. D:\boost_1_55_0
|
||||
OPENSSL_ROOT_DIR : For OpenSSL, e.g. D:\OpenSSL-Win32
|
||||
|
||||
only required by libthriftnb:
|
||||
|
||||
LIBEVENT_ROOT_DIR : For Libevent e.g. D:\libevent-2.0.21-stable
|
||||
|
||||
See /3rdparty.user for more details.
|
||||
|
||||
Thrift is divided into two libraries.
|
||||
|
||||
* libthrift - The core Thrift library contains all the core Thrift code. It requires
|
||||
boost shared pointers, pthreads, and librt.
|
||||
|
||||
* libthriftnb - This library contains the Thrift nonblocking server, which uses libevent.
|
||||
To link this library you will also need to link libevent.
|
||||
|
||||
## Linking Against Thrift
|
||||
|
||||
You need to link your project that uses thrift against all the thrift
|
||||
dependencies; in the case of libthrift, boost and for
|
||||
libthriftnb, libevent.
|
||||
|
||||
In the project properties you must also set HAVE_CONFIG_H as force include
|
||||
the config header: "windows/confg.h"
|
||||
|
||||
## Dependencies
|
||||
|
||||
boost shared pointers
|
||||
http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
|
||||
boost thread
|
||||
http://www.boost.org/doc/libs/release/doc/html/thread.html
|
||||
|
||||
libevent (for libthriftnb only)
|
||||
http://monkey.org/~provos/libevent/
|
||||
|
||||
## Notes on boost thread (static vs shared):
|
||||
|
||||
By default lib/cpp/windows/force_inc.h defines:
|
||||
|
||||
#define BOOST_ALL_NO_LIB 1
|
||||
#define BOOST_THREAD_NO_LIB 1
|
||||
|
||||
This has for effect to have the host application linking against Thrift
|
||||
to have to link with boost thread as a static library.
|
||||
|
||||
If you wanted instead to link with boost thread as a shared library,
|
||||
you'll need to uncomment those two lines, and recompile.
|
||||
|
||||
## Windows version compatibility
|
||||
|
||||
The Thrift library targets Windows XP for broadest compatbility. A notable
|
||||
difference is in the Windows-specific implementation of the socket poll
|
||||
function. To target Vista, Win7 or other versions, comment out the line
|
||||
|
||||
#define TARGET_WIN_XP.
|
||||
|
||||
## Named Pipes
|
||||
|
||||
Named Pipe transport has been added in the TPipe and TPipeServer classes. This
|
||||
is currently Windows-only. Named pipe transport for *NIX has not been
|
||||
implemented. Domain sockets are a better choice for local IPC under non-Windows
|
||||
OS's. *NIX named pipes only support 1:1 client-server connection.
|
||||
|
||||
# Thrift/SSL
|
||||
|
||||
## Scope
|
||||
|
||||
This SSL only supports blocking mode socket I/O. It can only be used with
|
||||
TSimpleServer, TThreadedServer, and TThreadPoolServer.
|
||||
|
||||
## Implementation
|
||||
|
||||
There're two main classes TSSLSocketFactory and TSSLSocket. Instances of
|
||||
TSSLSocket are always created from TSSLSocketFactory.
|
||||
|
||||
PosixSSLThreadFactory creates PosixSSLThread. The only difference from the
|
||||
PthreadThread type is that it cleanups OpenSSL error queue upon exiting
|
||||
the thread. Ideally, OpenSSL APIs should only be called from PosixSSLThread.
|
||||
|
||||
## How to use SSL APIs
|
||||
|
||||
This is for demo. In real code, typically only one TSSLSocketFactory
|
||||
instance is needed.
|
||||
|
||||
shared_ptr<TSSLSocketFactory> getSSLSocketFactory() {
|
||||
shared_ptr<TSSLSocketFactory> factory(new TSSLSocketFactory());
|
||||
// client: load trusted certificates
|
||||
factory->loadTrustedCertificates("my-trusted-ca-certificates.pem");
|
||||
// client: optionally set your own access manager, otherwise,
|
||||
// the default client access manager will be loaded.
|
||||
|
||||
factory->loadCertificate("my-certificate-signed-by-ca.pem");
|
||||
factory->loadPrivateKey("my-private-key.pem");
|
||||
// server: optionally setup access manager
|
||||
// shared_ptr<AccessManager> accessManager(new MyAccessManager);
|
||||
// factory->access(accessManager);
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
client code sample
|
||||
|
||||
shared_ptr<TSSLSocketFactory> factory = getSSLSocketFactory();
|
||||
shared_ptr<TSocket> socket = factory.createSocket(host, port);
|
||||
shared_ptr<TBufferedTransport> transport(new TBufferedTransport(socket));
|
||||
...
|
||||
|
||||
|
||||
server code sample
|
||||
|
||||
shared_ptr<TSSLSocketFactory> factory = getSSLSocketFactory();
|
||||
shared_ptr<TSSLServerSocket> socket(new TSSLServerSocket(port, factory));
|
||||
shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory));
|
||||
...
|
||||
|
||||
## AccessManager
|
||||
|
||||
AccessManager defines a callback interface. It has three callback methods:
|
||||
|
||||
(a) Decision verify(const sockaddr_storage& sa);
|
||||
|
||||
(b) Decision verify(const string& host, const char* name, int size);
|
||||
|
||||
(c) Decision verify(const sockaddr_storage& sa, const char* data, int size);
|
||||
|
||||
After SSL handshake completes, additional checks are conducted. Application
|
||||
is given the chance to decide whether or not to continue the conversation
|
||||
with the remote. Application is queried through the above three "verify"
|
||||
method. They are called at different points of the verification process.
|
||||
|
||||
Decisions can be one of ALLOW, DENY, and SKIP. ALLOW and DENY means the
|
||||
conversation should be continued or disconnected, respectively. ALLOW and
|
||||
DENY decision stops the verification process. SKIP means there's no decision
|
||||
based on the given input, continue the verification process.
|
||||
|
||||
First, (a) is called with the remote IP. It is called once at the beginning.
|
||||
"sa" is the IP address of the remote peer.
|
||||
|
||||
Then, the certificate of remote peer is loaded. SubjectAltName extensions
|
||||
are extracted and sent to application for verification. When a DNS
|
||||
subjectAltName field is extracted, (b) is called. When an IP subjectAltName
|
||||
field is extracted, (c) is called.
|
||||
|
||||
The "host" in (b) is the value from TSocket::getHost() if this is a client
|
||||
side socket, or TSocket::getPeerHost() if this is a server side socket. The
|
||||
reason is client side socket initiates the connection. TSocket::getHost()
|
||||
is the remote host name. On server side, the remote host name is unknown
|
||||
unless it's retrieved through TSocket::getPeerHost(). Either way, "host"
|
||||
should be the remote host name. Keep in mind, if TSocket::getPeerHost()
|
||||
failed, it would return the remote host name in numeric format.
|
||||
|
||||
If all subjectAltName extensions were "skipped", the common name field would
|
||||
be checked. It is sent to application through (c), where "sa" is the remote
|
||||
IP address. "data" is the IP address extracted from subjectAltName IP
|
||||
extension, and "size" is the length of the extension data.
|
||||
|
||||
If any of the above "verify" methods returned a decision ALLOW or DENY, the
|
||||
verification process would be stopped.
|
||||
|
||||
If any of the above "verify" methods returned SKIP, that decision would be
|
||||
ignored and the verification process would move on till the last item is
|
||||
examined. At that point, if there's still no decision, the connection is
|
||||
terminated.
|
||||
|
||||
Thread safety, an access manager should not store state information if it's
|
||||
to be used by many SSL sockets.
|
||||
|
||||
## SIGPIPE signal
|
||||
|
||||
Applications running OpenSSL over network connections may crash if SIGPIPE
|
||||
is not ignored. This happens when they receive a connection reset by remote
|
||||
peer exception, which somehow triggers a SIGPIPE signal. If not handled,
|
||||
this signal would kill the application.
|
||||
|
||||
## How to run test client/server in SSL mode
|
||||
|
||||
The server and client expects the followings from the directory /test/
|
||||
|
||||
- keys/server.crt
|
||||
- keys/server.key
|
||||
- keys/CA.pem
|
||||
|
||||
The file names are hard coded in the source code. You need to create these
|
||||
certificates before you can run the test code in SSL mode. Make sure at least
|
||||
one of the followings is included in "keys/server.crt",
|
||||
|
||||
- subjectAltName, DNS localhost
|
||||
- subjectAltName, IP 127.0.0.1
|
||||
- common name, localhost
|
||||
|
||||
Run within /test/ folder,
|
||||
|
||||
./cpp/TestServer --ssl &
|
||||
./cpp/TestClient --ssl
|
||||
|
||||
If "-h <host>" is used to run client, the above "localhost" in the above
|
||||
keys/server.crt has to be replaced with that host name.
|
||||
|
||||
## TSSLSocketFactory::randomize()
|
||||
|
||||
The default implementation of OpenSSLSocketFactory::randomize() simply calls
|
||||
OpenSSL's RAND_poll() when OpenSSL library is first initialized.
|
||||
|
||||
The PRNG seed is key to the application security. This method should be
|
||||
overridden if it's not strong enough for you.
|
4
vendor/git.apache.org/thrift.git/lib/cpp/coding_standards.md
generated
vendored
Normal file
4
vendor/git.apache.org/thrift.git/lib/cpp/coding_standards.md
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
Please follow [General Coding Standards](/doc/coding_standards.md)
|
||||
|
||||
* see .clang-format in root dir for settings of accepted format
|
||||
* clang-format (3.5 or newer) can be used to automaticaly reformat code ('make style' command)
|
363
vendor/git.apache.org/thrift.git/lib/cpp/libthrift.vcxproj
generated
vendored
Normal file
363
vendor/git.apache.org/thrift.git/lib/cpp/libthrift.vcxproj
generated
vendored
Normal file
|
@ -0,0 +1,363 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug-mt|Win32">
|
||||
<Configuration>Debug-mt</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug-mt|x64">
|
||||
<Configuration>Debug-mt</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release-mt|Win32">
|
||||
<Configuration>Release-mt</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release-mt|x64">
|
||||
<Configuration>Release-mt</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\thrift\async\TAsyncChannel.cpp"/>
|
||||
<ClCompile Include="src\thrift\async\TConcurrentClientSyncInfo.cpp"/>
|
||||
<ClCompile Include="src\thrift\concurrency\BoostMonitor.cpp" />
|
||||
<ClCompile Include="src\thrift\concurrency\BoostMutex.cpp" />
|
||||
<ClCompile Include="src\thrift\concurrency\BoostThreadFactory.cpp" />
|
||||
<ClCompile Include="src\thrift\concurrency\StdThreadFactory.cpp" />
|
||||
<ClCompile Include="src\thrift\concurrency\ThreadManager.cpp"/>
|
||||
<ClCompile Include="src\thrift\concurrency\TimerManager.cpp"/>
|
||||
<ClCompile Include="src\thrift\concurrency\Util.cpp"/>
|
||||
<ClCompile Include="src\thrift\processor\PeekProcessor.cpp"/>
|
||||
<ClCompile Include="src\thrift\protocol\TBase64Utils.cpp" />
|
||||
<ClCompile Include="src\thrift\protocol\TDebugProtocol.cpp"/>
|
||||
<ClCompile Include="src\thrift\protocol\TJSONProtocol.cpp"/>
|
||||
<ClCompile Include="src\thrift\protocol\TProtocol.cpp"/>
|
||||
<ClCompile Include="src\thrift\protocol\TMultiplexedProtocol.cpp"/>
|
||||
<ClCompile Include="src\thrift\server\TSimpleServer.cpp"/>
|
||||
<ClCompile Include="src\thrift\server\TThreadPoolServer.cpp"/>
|
||||
<ClCompile Include="src\thrift\server\TThreadedServer.cpp"/>
|
||||
<ClCompile Include="src\thrift\TApplicationException.cpp"/>
|
||||
<ClCompile Include="src\thrift\TOutput.cpp"/>
|
||||
<ClCompile Include="src\thrift\transport\TBufferTransports.cpp"/>
|
||||
<ClCompile Include="src\thrift\transport\TFDTransport.cpp" />
|
||||
<ClCompile Include="src\thrift\transport\THttpClient.cpp" />
|
||||
<ClCompile Include="src\thrift\transport\THttpServer.cpp" />
|
||||
<ClCompile Include="src\thrift\transport\THttpTransport.cpp"/>
|
||||
<ClCompile Include="src\thrift\transport\TPipe.cpp" />
|
||||
<ClCompile Include="src\thrift\transport\TPipeServer.cpp" />
|
||||
<ClCompile Include="src\thrift\transport\TServerSocket.cpp"/>
|
||||
<ClCompile Include="src\thrift\transport\TSimpleFileTransport.cpp" />
|
||||
<ClCompile Include="src\thrift\transport\TFileTransport.cpp" />
|
||||
<ClCompile Include="src\thrift\transport\TSocket.cpp"/>
|
||||
<ClCompile Include="src\thrift\transport\TSSLSocket.cpp"/>
|
||||
<ClCompile Include="src\thrift\transport\TTransportException.cpp"/>
|
||||
<ClCompile Include="src\thrift\transport\TTransportUtils.cpp"/>
|
||||
<ClCompile Include="src\thrift\windows\GetTimeOfDay.cpp" />
|
||||
<ClCompile Include="src\thrift\windows\OverlappedSubmissionThread.cpp" />
|
||||
<ClCompile Include="src\thrift\windows\SocketPair.cpp" />
|
||||
<ClCompile Include="src\thrift\windows\TWinsockSingleton.cpp" />
|
||||
<ClCompile Include="src\thrift\windows\WinFcntl.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\thrift\async\TAsyncChannel.h" />
|
||||
<ClInclude Include="src\thrift\async\TConcurrentClientSyncInfo.h" />
|
||||
<ClInclude Include="src\thrift\concurrency\BoostThreadFactory.h" />
|
||||
<ClInclude Include="src\thrift\concurrency\StdThreadFactory.h" />
|
||||
<ClInclude Include="src\thrift\concurrency\Exception.h" />
|
||||
<ClInclude Include="src\thrift\concurrency\PlatformThreadFactory.h" />
|
||||
<ClInclude Include="src\thrift\processor\PeekProcessor.h" />
|
||||
<ClInclude Include="src\thrift\processor\TMultiplexedProcessor.h" />
|
||||
<ClInclude Include="src\thrift\protocol\TBinaryProtocol.h" />
|
||||
<ClInclude Include="src\thrift\protocol\TDebugProtocol.h" />
|
||||
<ClInclude Include="src\thrift\protocol\TJSONProtocol.h" />
|
||||
<ClInclude Include="src\thrift\protocol\TMultiplexedProtocol.h" />
|
||||
<ClInclude Include="src\thrift\protocol\TProtocol.h" />
|
||||
<ClInclude Include="src\thrift\protocol\TVirtualProtocol.h" />
|
||||
<ClInclude Include="src\thrift\server\TServer.h" />
|
||||
<ClInclude Include="src\thrift\server\TSimpleServer.h" />
|
||||
<ClInclude Include="src\thrift\server\TThreadPoolServer.h" />
|
||||
<ClInclude Include="src\thrift\server\TThreadedServer.h" />
|
||||
<ClInclude Include="src\thrift\TApplicationException.h" />
|
||||
<ClInclude Include="src\thrift\Thrift.h" />
|
||||
<ClInclude Include="src\thrift\TOutput.h" />
|
||||
<ClInclude Include="src\thrift\TProcessor.h" />
|
||||
<ClInclude Include="src\thrift\transport\TBufferTransports.h" />
|
||||
<ClInclude Include="src\thrift\transport\TFDTransport.h" />
|
||||
<ClInclude Include="src\thrift\transport\TFileTransport.h" />
|
||||
<ClInclude Include="src\thrift\transport\THttpClient.h" />
|
||||
<ClInclude Include="src\thrift\transport\THttpServer.h" />
|
||||
<ClInclude Include="src\thrift\transport\TPipe.h" />
|
||||
<ClInclude Include="src\thrift\transport\TPipeServer.h" />
|
||||
<ClInclude Include="src\thrift\transport\TServerSocket.h" />
|
||||
<ClInclude Include="src\thrift\transport\TServerTransport.h" />
|
||||
<ClInclude Include="src\thrift\transport\TSimpleFileTransport.h" />
|
||||
<ClInclude Include="src\thrift\transport\TSocket.h" />
|
||||
<ClInclude Include="src\thrift\transport\TSSLSocket.h" />
|
||||
<ClInclude Include="src\thrift\transport\TTransport.h" />
|
||||
<ClInclude Include="src\thrift\transport\TTransportException.h" />
|
||||
<ClInclude Include="src\thrift\transport\TTransportUtils.h" />
|
||||
<ClInclude Include="src\thrift\transport\TVirtualTransport.h" />
|
||||
<ClInclude Include="src\thrift\windows\config.h" />
|
||||
<ClInclude Include="src\thrift\windows\GetTimeOfDay.h" />
|
||||
<ClInclude Include="src\thrift\windows\Operators.h" />
|
||||
<ClInclude Include="src\thrift\windows\OverlappedSubmissionThread.h" />
|
||||
<ClInclude Include="src\thrift\windows\SocketPair.h" />
|
||||
<ClInclude Include="src\thrift\windows\TWinsockSingleton.h" />
|
||||
<ClInclude Include="src\thrift\windows\WinFcntl.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="src\thrift\protocol\TBinaryProtocol.tcc" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{DD26F57E-60F2-4F37-A616-D219A9BF338F}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>thrift</RootNamespace>
|
||||
<ProjectName>libthrift</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-mt|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-mt|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-mt|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-mt|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="3rdparty.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug-mt|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="3rdparty.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="3rdparty.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug-mt|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="3rdparty.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="3rdparty.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-mt|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="3rdparty.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="3rdparty.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-mt|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="3rdparty.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IncludePath>$(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(OPENSSL_ROOT_DIR)\include\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-mt|Win32'">
|
||||
<IncludePath>$(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(OPENSSL_ROOT_DIR)\include\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IncludePath>$(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(OPENSSL_ROOT_DIR)\include\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-mt|x64'">
|
||||
<IncludePath>$(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(OPENSSL_ROOT_DIR)\include\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<IncludePath>$(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(OPENSSL_ROOT_DIR)\include\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-mt|Win32'">
|
||||
<IncludePath>$(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(OPENSSL_ROOT_DIR)\include\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<IncludePath>$(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(OPENSSL_ROOT_DIR)\include\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-mt|x64'">
|
||||
<IncludePath>$(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(OPENSSL_ROOT_DIR)\include\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H=1;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ProgramDataBaseFileName>$(IntDir)libthrift.pdb</ProgramDataBaseFileName>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-mt|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H=1;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ProgramDataBaseFileName>$(IntDir)libthrift.pdb</ProgramDataBaseFileName>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H=1;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-mt|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H=1;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H=1;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ProgramDataBaseFileName>$(IntDir)libthrift.pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-mt|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H=1;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ProgramDataBaseFileName>$(IntDir)libthrift.pdb</ProgramDataBaseFileName>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H=1;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-mt|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H=1;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
283
vendor/git.apache.org/thrift.git/lib/cpp/libthrift.vcxproj.filters
generated
vendored
Normal file
283
vendor/git.apache.org/thrift.git/lib/cpp/libthrift.vcxproj.filters
generated
vendored
Normal file
|
@ -0,0 +1,283 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\thrift\transport\TBufferTransports.cpp">
|
||||
<Filter>transport</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\TOutput.cpp" />
|
||||
<ClCompile Include="src\thrift\TApplicationException.cpp" />
|
||||
<ClCompile Include="src\thrift\windows\StdAfx.cpp">
|
||||
<Filter>windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\transport\TTransportException.cpp">
|
||||
<Filter>transport</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\windows\GetTimeOfDay.cpp">
|
||||
<Filter>windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\concurrency\ThreadManager.cpp">
|
||||
<Filter>concurrency</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\concurrency\TimerManager.cpp">
|
||||
<Filter>concurrency</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\concurrency\Util.cpp">
|
||||
<Filter>concurrency</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\protocol\TDebugProtocol.cpp">
|
||||
<Filter>protocol</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\protocol\TBase64Utils.cpp">
|
||||
<Filter>protocol</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\protocol\TJSONProtocol.cpp">
|
||||
<Filter>protocol</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\protocol\TMultiplexedProtocol.cpp">
|
||||
<Filter>protocol</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\transport\TFDTransport.cpp">
|
||||
<Filter>transport</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\transport\TFileTransport.cpp">
|
||||
<Filter>transport</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\transport\TSimpleFileTransport.cpp">
|
||||
<Filter>transport</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\transport\THttpTransport.cpp">
|
||||
<Filter>transport</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\transport\THttpClient.cpp">
|
||||
<Filter>transport</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\transport\THttpServer.cpp">
|
||||
<Filter>transport</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\transport\TSSLSocket.cpp">
|
||||
<Filter>transport</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\transport\TTransportUtils.cpp">
|
||||
<Filter>transport</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\server\TSimpleServer.cpp">
|
||||
<Filter>server</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\server\TThreadPoolServer.cpp">
|
||||
<Filter>server</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\server\TThreadedServer.cpp">
|
||||
<Filter>server</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\async\TAsyncChannel.cpp">
|
||||
<Filter>async</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\async\TConcurrentClientSyncInfo.cpp">
|
||||
<Filter>async</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\processor\PeekProcessor.cpp">
|
||||
<Filter>processor</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\transport\TServerSocket.cpp">
|
||||
<Filter>transport</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\transport\TSocket.cpp">
|
||||
<Filter>transport</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\windows\TWinsockSingleton.cpp">
|
||||
<Filter>windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\windows\SocketPair.cpp">
|
||||
<Filter>windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\concurrency\BoostMonitor.cpp">
|
||||
<Filter>concurrency</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\concurrency\BoostMutex.cpp">
|
||||
<Filter>concurrency</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\concurrency\BoostThreadFactory.cpp">
|
||||
<Filter>concurrency</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\concurrency\StdThreadFactory.cpp">
|
||||
<Filter>concurrency</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\windows\WinFcntl.cpp">
|
||||
<Filter>windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\transport\TPipe.cpp">
|
||||
<Filter>transport</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\transport\TPipeServer.cpp">
|
||||
<Filter>transport</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\thrift\transport\TBufferTransports.h">
|
||||
<Filter>transport</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\transport\TSocket.h">
|
||||
<Filter>transport</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\protocol\TBinaryProtocol.h">
|
||||
<Filter>protocol</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\Thrift.h" />
|
||||
<ClInclude Include="src\thrift\TProcessor.h" />
|
||||
<ClInclude Include="src\thrift\TApplicationException.h" />
|
||||
<ClInclude Include="src\thrift\windows\StdAfx.h">
|
||||
<Filter>windows</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\windows\TargetVersion.h">
|
||||
<Filter>windows</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\concurrency\Exception.h">
|
||||
<Filter>concurrency</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\transport\TVirtualTransport.h">
|
||||
<Filter>transport</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\transport\TTransport.h">
|
||||
<Filter>transport</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\transport\TTransportException.h">
|
||||
<Filter>transport</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\windows\GetTimeOfDay.h">
|
||||
<Filter>windows</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\transport\TServerTransport.h">
|
||||
<Filter>transport</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\windows\config.h">
|
||||
<Filter>windows</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\protocol\TProtocol.h">
|
||||
<Filter>protocol</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\protocol\TVirtualProtocol.h">
|
||||
<Filter>protocol</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\server\TServer.h">
|
||||
<Filter>server</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\server\TSimpleServer.h">
|
||||
<Filter>server</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\server\TThreadPoolServer.h">
|
||||
<Filter>server</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\server\TThreadedServer.h">
|
||||
<Filter>server</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\async\TAsyncChannel.h">
|
||||
<Filter>async</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\async\TConcurrentClientSyncInfo.h">
|
||||
<Filter>async</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\processor\PeekProcessor.h">
|
||||
<Filter>processor</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\processor\TMultiplexedProcessor.h">
|
||||
<Filter>processor</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\transport\TFDTransport.h">
|
||||
<Filter>transport</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\transport\TFileTransport.h">
|
||||
<Filter>transport</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\transport\THttpClient.h">
|
||||
<Filter>transport</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\transport\THttpServer.h">
|
||||
<Filter>transport</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\transport\TSSLSocket.h">
|
||||
<Filter>transport</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\transport\TTransportUtils.h">
|
||||
<Filter>transport</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\transport\TSimpleFileTransport.h">
|
||||
<Filter>transport</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\protocol\TJSONProtocol.h">
|
||||
<Filter>protocol</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\protocol\TMultiplexedProtocol.h">
|
||||
<Filter>protocol</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\protocol\TDebugProtocol.h">
|
||||
<Filter>protocol</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\transport\TServerSocket.h">
|
||||
<Filter>transport</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\windows\Operators.h">
|
||||
<Filter>windows</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\windows\TWinsockSingleton.h">
|
||||
<Filter>windows</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\windows\SocketPair.h">
|
||||
<Filter>windows</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\windows\force_inc.h">
|
||||
<Filter>windows</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\concurrency\BoostThreadFactory.h">
|
||||
<Filter>concurrency</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\concurrency\StdThreadFactory.h">
|
||||
<Filter>concurrency</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\concurrency\PlatformThreadFactory.h">
|
||||
<Filter>concurrency</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\windows\WinFcntl.h">
|
||||
<Filter>windows</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\transport\TPipe.h">
|
||||
<Filter>transport</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\transport\TPipeServer.h">
|
||||
<Filter>transport</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="protocol">
|
||||
<UniqueIdentifier>{07ced19b-b72a-4105-9ffb-6d2bcf64497e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="transport">
|
||||
<UniqueIdentifier>{e9f61404-1148-4103-bd6f-e5869d37fa79}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="windows">
|
||||
<UniqueIdentifier>{2814002a-3c68-427e-b0eb-33acd2f406ae}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="concurrency">
|
||||
<UniqueIdentifier>{addd4707-dbaa-4d0c-bef6-fff8be7b495a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="server">
|
||||
<UniqueIdentifier>{f55a8e9b-6959-487f-a396-c31b4d6c61d6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="async">
|
||||
<UniqueIdentifier>{d526885b-1b3e-4ee3-8027-e694fe98ad63}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="processor">
|
||||
<UniqueIdentifier>{8f428da8-5a83-44fb-9578-de935fb415e1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="windows\tr1">
|
||||
<UniqueIdentifier>{eea10406-3380-4f2d-9365-c26fa2875dae}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="src\thrift\protocol\TBinaryProtocol.tcc">
|
||||
<Filter>protocol</Filter>
|
||||
</None>
|
||||
<None Include="src\thrift\windows\tr1\functional">
|
||||
<Filter>windows\tr1</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
293
vendor/git.apache.org/thrift.git/lib/cpp/libthriftnb.vcxproj
generated
vendored
Executable file
293
vendor/git.apache.org/thrift.git/lib/cpp/libthriftnb.vcxproj
generated
vendored
Executable file
|
@ -0,0 +1,293 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug-mt|Win32">
|
||||
<Configuration>Debug-mt</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug-mt|x64">
|
||||
<Configuration>Debug-mt</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release-mt|Win32">
|
||||
<Configuration>Release-mt</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release-mt|x64">
|
||||
<Configuration>Release-mt</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\thrift\async\TAsyncProtocolProcessor.cpp"/>
|
||||
<ClCompile Include="src\thrift\async\TEvhttpClientChannel.cpp"/>
|
||||
<ClCompile Include="src\thrift\async\TEvhttpServer.cpp"/>
|
||||
<ClCompile Include="src\thrift\server\TNonblockingServer.cpp"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\thrift\async\TAsyncProtocolProcessor.h" />
|
||||
<ClInclude Include="src\thrift\async\TEvhttpClientChannel.h" />
|
||||
<ClInclude Include="src\thrift\async\TEvhttpServer.h" />
|
||||
<ClInclude Include="src\thrift\server\TNonblockingServer.h" />
|
||||
<ClInclude Include="src\thrift\windows\config.h" />
|
||||
<ClInclude Include="src\thrift\windows\force_inc.h" />
|
||||
<ClInclude Include="src\thrift\windows\TargetVersion.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{D8696CCE-7D46-4659-B432-91754A41DEB0}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>libthriftnb</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-mt|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-mt|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-mt|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-mt|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="3rdparty.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug-mt|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="3rdparty.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="3rdparty.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug-mt|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="3rdparty.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="3rdparty.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-mt|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="3rdparty.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="3rdparty.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-mt|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="3rdparty.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IncludePath>$(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(LIBEVENT_ROOT)\WIN32-Code\;$(LIBEVENT_ROOT)\include;$(LIBEVENT_ROOT)\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-mt|Win32'">
|
||||
<IncludePath>$(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(LIBEVENT_ROOT)\WIN32-Code\;$(LIBEVENT_ROOT)\include;$(LIBEVENT_ROOT)\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IncludePath>$(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(LIBEVENT_ROOT)\WIN32-Code\;$(LIBEVENT_ROOT)\include;$(LIBEVENT_ROOT)\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-mt|x64'">
|
||||
<IncludePath>$(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(LIBEVENT_ROOT)\WIN32-Code\;$(LIBEVENT_ROOT)\include;$(LIBEVENT_ROOT)\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<IncludePath>$(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(LIBEVENT_ROOT)\WIN32-Code\;$(LIBEVENT_ROOT)\include;$(LIBEVENT_ROOT)\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-mt|Win32'">
|
||||
<IncludePath>$(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(LIBEVENT_ROOT)\WIN32-Code\;$(LIBEVENT_ROOT)\include;$(LIBEVENT_ROOT)\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<IncludePath>$(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(LIBEVENT_ROOT)\WIN32-Code\;$(LIBEVENT_ROOT)\include;$(LIBEVENT_ROOT)\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-mt|x64'">
|
||||
<IncludePath>$(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(LIBEVENT_ROOT)\WIN32-Code\;$(LIBEVENT_ROOT)\include;$(LIBEVENT_ROOT)\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H=1;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ProgramDataBaseFileName>$(IntDir)libthriftnb.pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-mt|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H=1;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ProgramDataBaseFileName>$(IntDir)libthriftnb.pdb</ProgramDataBaseFileName>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H=1;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-mt|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H=1;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H=1;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ProgramDataBaseFileName>$(IntDir)libthriftnb.pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-mt|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H=1;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ProgramDataBaseFileName>$(IntDir)libthriftnb.pdb</ProgramDataBaseFileName>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H=1;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-mt|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>HAVE_CONFIG_H=1;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
57
vendor/git.apache.org/thrift.git/lib/cpp/libthriftnb.vcxproj.filters
generated
vendored
Normal file
57
vendor/git.apache.org/thrift.git/lib/cpp/libthriftnb.vcxproj.filters
generated
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="server">
|
||||
<UniqueIdentifier>{bf449d92-4be8-4f6f-a010-c536f57c6f13}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="async">
|
||||
<UniqueIdentifier>{0294d0a6-ce46-4be8-a659-826d6e98ae41}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="windows">
|
||||
<UniqueIdentifier>{60fc9e5e-0866-4aba-8662-439bb4a461d3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\thrift\server\TNonblockingServer.cpp">
|
||||
<Filter>server</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\async\TEvhttpClientChannel.cpp">
|
||||
<Filter>async</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\async\TEvhttpServer.cpp">
|
||||
<Filter>async</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\async\TAsyncProtocolProcessor.cpp">
|
||||
<Filter>async</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\thrift\windows\StdAfx.cpp">
|
||||
<Filter>windows</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\thrift\server\TNonblockingServer.h">
|
||||
<Filter>server</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\async\TEvhttpClientChannel.h">
|
||||
<Filter>async</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\async\TEvhttpServer.h">
|
||||
<Filter>async</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\async\TAsyncProtocolProcessor.h">
|
||||
<Filter>async</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\windows\config.h">
|
||||
<Filter>windows</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\windows\StdAfx.h">
|
||||
<Filter>windows</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\windows\TargetVersion.h">
|
||||
<Filter>windows</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\thrift\windows\force_inc.h">
|
||||
<Filter>windows</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
81
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/TApplicationException.cpp
generated
vendored
Normal file
81
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/TApplicationException.cpp
generated
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/TApplicationException.h>
|
||||
#include <thrift/protocol/TProtocol.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
|
||||
uint32_t TApplicationException::read(apache::thrift::protocol::TProtocol* iprot) {
|
||||
uint32_t xfer = 0;
|
||||
std::string fname;
|
||||
apache::thrift::protocol::TType ftype;
|
||||
int16_t fid;
|
||||
|
||||
xfer += iprot->readStructBegin(fname);
|
||||
|
||||
while (true) {
|
||||
xfer += iprot->readFieldBegin(fname, ftype, fid);
|
||||
if (ftype == apache::thrift::protocol::T_STOP) {
|
||||
break;
|
||||
}
|
||||
switch (fid) {
|
||||
case 1:
|
||||
if (ftype == apache::thrift::protocol::T_STRING) {
|
||||
xfer += iprot->readString(message_);
|
||||
} else {
|
||||
xfer += iprot->skip(ftype);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (ftype == apache::thrift::protocol::T_I32) {
|
||||
int32_t type;
|
||||
xfer += iprot->readI32(type);
|
||||
type_ = (TApplicationExceptionType)type;
|
||||
} else {
|
||||
xfer += iprot->skip(ftype);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
xfer += iprot->skip(ftype);
|
||||
break;
|
||||
}
|
||||
xfer += iprot->readFieldEnd();
|
||||
}
|
||||
|
||||
xfer += iprot->readStructEnd();
|
||||
return xfer;
|
||||
}
|
||||
|
||||
uint32_t TApplicationException::write(apache::thrift::protocol::TProtocol* oprot) const {
|
||||
uint32_t xfer = 0;
|
||||
xfer += oprot->writeStructBegin("TApplicationException");
|
||||
xfer += oprot->writeFieldBegin("message", apache::thrift::protocol::T_STRING, 1);
|
||||
xfer += oprot->writeString(message_);
|
||||
xfer += oprot->writeFieldEnd();
|
||||
xfer += oprot->writeFieldBegin("type", apache::thrift::protocol::T_I32, 2);
|
||||
xfer += oprot->writeI32(type_);
|
||||
xfer += oprot->writeFieldEnd();
|
||||
xfer += oprot->writeFieldStop();
|
||||
xfer += oprot->writeStructEnd();
|
||||
return xfer;
|
||||
}
|
||||
}
|
||||
} // apache::thrift
|
115
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/TApplicationException.h
generated
vendored
Normal file
115
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/TApplicationException.h
generated
vendored
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_TAPPLICATIONEXCEPTION_H_
|
||||
#define _THRIFT_TAPPLICATIONEXCEPTION_H_ 1
|
||||
|
||||
#include <thrift/Thrift.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
|
||||
namespace protocol {
|
||||
class TProtocol;
|
||||
}
|
||||
|
||||
class TApplicationException : public TException {
|
||||
public:
|
||||
/**
|
||||
* Error codes for the various types of exceptions.
|
||||
*/
|
||||
enum TApplicationExceptionType {
|
||||
UNKNOWN = 0,
|
||||
UNKNOWN_METHOD = 1,
|
||||
INVALID_MESSAGE_TYPE = 2,
|
||||
WRONG_METHOD_NAME = 3,
|
||||
BAD_SEQUENCE_ID = 4,
|
||||
MISSING_RESULT = 5,
|
||||
INTERNAL_ERROR = 6,
|
||||
PROTOCOL_ERROR = 7,
|
||||
INVALID_TRANSFORM = 8,
|
||||
INVALID_PROTOCOL = 9,
|
||||
UNSUPPORTED_CLIENT_TYPE = 10
|
||||
};
|
||||
|
||||
TApplicationException() : TException(), type_(UNKNOWN) {}
|
||||
|
||||
TApplicationException(TApplicationExceptionType type) : TException(), type_(type) {}
|
||||
|
||||
TApplicationException(const std::string& message) : TException(message), type_(UNKNOWN) {}
|
||||
|
||||
TApplicationException(TApplicationExceptionType type, const std::string& message)
|
||||
: TException(message), type_(type) {}
|
||||
|
||||
virtual ~TApplicationException() throw() {}
|
||||
|
||||
/**
|
||||
* Returns an error code that provides information about the type of error
|
||||
* that has occurred.
|
||||
*
|
||||
* @return Error code
|
||||
*/
|
||||
TApplicationExceptionType getType() const { return type_; }
|
||||
|
||||
virtual const char* what() const throw() {
|
||||
if (message_.empty()) {
|
||||
switch (type_) {
|
||||
case UNKNOWN:
|
||||
return "TApplicationException: Unknown application exception";
|
||||
case UNKNOWN_METHOD:
|
||||
return "TApplicationException: Unknown method";
|
||||
case INVALID_MESSAGE_TYPE:
|
||||
return "TApplicationException: Invalid message type";
|
||||
case WRONG_METHOD_NAME:
|
||||
return "TApplicationException: Wrong method name";
|
||||
case BAD_SEQUENCE_ID:
|
||||
return "TApplicationException: Bad sequence identifier";
|
||||
case MISSING_RESULT:
|
||||
return "TApplicationException: Missing result";
|
||||
case INTERNAL_ERROR:
|
||||
return "TApplicationException: Internal error";
|
||||
case PROTOCOL_ERROR:
|
||||
return "TApplicationException: Protocol error";
|
||||
case INVALID_TRANSFORM:
|
||||
return "TApplicationException: Invalid transform";
|
||||
case INVALID_PROTOCOL:
|
||||
return "TApplicationException: Invalid protocol";
|
||||
case UNSUPPORTED_CLIENT_TYPE:
|
||||
return "TApplicationException: Unsupported client type";
|
||||
default:
|
||||
return "TApplicationException: (Invalid exception type)";
|
||||
};
|
||||
} else {
|
||||
return message_.c_str();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t read(protocol::TProtocol* iprot);
|
||||
uint32_t write(protocol::TProtocol* oprot) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Error code
|
||||
*/
|
||||
TApplicationExceptionType type_;
|
||||
};
|
||||
}
|
||||
} // apache::thrift
|
||||
|
||||
#endif // #ifndef _THRIFT_TAPPLICATIONEXCEPTION_H_
|
38
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/TBase.h
generated
vendored
Normal file
38
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/TBase.h
generated
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_TBASE_H_
|
||||
#define _THRIFT_TBASE_H_ 1
|
||||
|
||||
#include <thrift/Thrift.h>
|
||||
#include <thrift/protocol/TProtocol.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
|
||||
class TBase {
|
||||
public:
|
||||
virtual ~TBase(){};
|
||||
virtual uint32_t read(protocol::TProtocol* iprot) = 0;
|
||||
virtual uint32_t write(protocol::TProtocol* oprot) const = 0;
|
||||
};
|
||||
}
|
||||
} // apache::thrift
|
||||
|
||||
#endif // #ifndef _THRIFT_TBASE_H_
|
141
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/TDispatchProcessor.h
generated
vendored
Normal file
141
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/TDispatchProcessor.h
generated
vendored
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
#ifndef _THRIFT_TDISPATCHPROCESSOR_H_
|
||||
#define _THRIFT_TDISPATCHPROCESSOR_H_ 1
|
||||
|
||||
#include <thrift/TProcessor.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
|
||||
/**
|
||||
* TDispatchProcessor is a helper class to parse the message header then call
|
||||
* another function to dispatch based on the function name.
|
||||
*
|
||||
* Subclasses must implement dispatchCall() to dispatch on the function name.
|
||||
*/
|
||||
template <class Protocol_>
|
||||
class TDispatchProcessorT : public TProcessor {
|
||||
public:
|
||||
virtual bool process(boost::shared_ptr<protocol::TProtocol> in,
|
||||
boost::shared_ptr<protocol::TProtocol> out,
|
||||
void* connectionContext) {
|
||||
protocol::TProtocol* inRaw = in.get();
|
||||
protocol::TProtocol* outRaw = out.get();
|
||||
|
||||
// Try to dynamic cast to the template protocol type
|
||||
Protocol_* specificIn = dynamic_cast<Protocol_*>(inRaw);
|
||||
Protocol_* specificOut = dynamic_cast<Protocol_*>(outRaw);
|
||||
if (specificIn && specificOut) {
|
||||
return processFast(specificIn, specificOut, connectionContext);
|
||||
}
|
||||
|
||||
// Log the fact that we have to use the slow path
|
||||
T_GENERIC_PROTOCOL(this, inRaw, specificIn);
|
||||
T_GENERIC_PROTOCOL(this, outRaw, specificOut);
|
||||
|
||||
std::string fname;
|
||||
protocol::TMessageType mtype;
|
||||
int32_t seqid;
|
||||
inRaw->readMessageBegin(fname, mtype, seqid);
|
||||
|
||||
// If this doesn't look like a valid call, log an error and return false so
|
||||
// that the server will close the connection.
|
||||
//
|
||||
// (The old generated processor code used to try to skip a T_STRUCT and
|
||||
// continue. However, that seems unsafe.)
|
||||
if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) {
|
||||
GlobalOutput.printf("received invalid message type %d from client", mtype);
|
||||
return false;
|
||||
}
|
||||
|
||||
return this->dispatchCall(inRaw, outRaw, fname, seqid, connectionContext);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool processFast(Protocol_* in, Protocol_* out, void* connectionContext) {
|
||||
std::string fname;
|
||||
protocol::TMessageType mtype;
|
||||
int32_t seqid;
|
||||
in->readMessageBegin(fname, mtype, seqid);
|
||||
|
||||
if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) {
|
||||
GlobalOutput.printf("received invalid message type %d from client", mtype);
|
||||
return false;
|
||||
}
|
||||
|
||||
return this->dispatchCallTemplated(in, out, fname, seqid, connectionContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* dispatchCall() methods must be implemented by subclasses
|
||||
*/
|
||||
virtual bool dispatchCall(apache::thrift::protocol::TProtocol* in,
|
||||
apache::thrift::protocol::TProtocol* out,
|
||||
const std::string& fname,
|
||||
int32_t seqid,
|
||||
void* callContext) = 0;
|
||||
|
||||
virtual bool dispatchCallTemplated(Protocol_* in,
|
||||
Protocol_* out,
|
||||
const std::string& fname,
|
||||
int32_t seqid,
|
||||
void* callContext) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Non-templatized version of TDispatchProcessor, that doesn't bother trying to
|
||||
* perform a dynamic_cast.
|
||||
*/
|
||||
class TDispatchProcessor : public TProcessor {
|
||||
public:
|
||||
virtual bool process(boost::shared_ptr<protocol::TProtocol> in,
|
||||
boost::shared_ptr<protocol::TProtocol> out,
|
||||
void* connectionContext) {
|
||||
std::string fname;
|
||||
protocol::TMessageType mtype;
|
||||
int32_t seqid;
|
||||
in->readMessageBegin(fname, mtype, seqid);
|
||||
|
||||
if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) {
|
||||
GlobalOutput.printf("received invalid message type %d from client", mtype);
|
||||
return false;
|
||||
}
|
||||
|
||||
return dispatchCall(in.get(), out.get(), fname, seqid, connectionContext);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual bool dispatchCall(apache::thrift::protocol::TProtocol* in,
|
||||
apache::thrift::protocol::TProtocol* out,
|
||||
const std::string& fname,
|
||||
int32_t seqid,
|
||||
void* callContext) = 0;
|
||||
};
|
||||
|
||||
// Specialize TDispatchProcessorT for TProtocol and TDummyProtocol just to use
|
||||
// the generic TDispatchProcessor.
|
||||
template <>
|
||||
class TDispatchProcessorT<protocol::TDummyProtocol> : public TDispatchProcessor {};
|
||||
template <>
|
||||
class TDispatchProcessorT<protocol::TProtocol> : public TDispatchProcessor {};
|
||||
}
|
||||
} // apache::thrift
|
||||
|
||||
#endif // _THRIFT_TDISPATCHPROCESSOR_H_
|
195
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/TLogging.h
generated
vendored
Normal file
195
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/TLogging.h
generated
vendored
Normal file
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_TLOGGING_H_
|
||||
#define _THRIFT_TLOGGING_H_ 1
|
||||
|
||||
#include <thrift/thrift-config.h>
|
||||
|
||||
/**
|
||||
* Contains utility macros for debugging and logging.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* T_GLOBAL_DEBUGGING_LEVEL = 0: all debugging turned off, debug macros undefined
|
||||
* T_GLOBAL_DEBUGGING_LEVEL = 1: all debugging turned on
|
||||
*/
|
||||
#define T_GLOBAL_DEBUGGING_LEVEL 0
|
||||
|
||||
/**
|
||||
* T_GLOBAL_LOGGING_LEVEL = 0: all logging turned off, logging macros undefined
|
||||
* T_GLOBAL_LOGGING_LEVEL = 1: all logging turned on
|
||||
*/
|
||||
#define T_GLOBAL_LOGGING_LEVEL 1
|
||||
|
||||
/**
|
||||
* Standard wrapper around fprintf what will prefix the file name and line
|
||||
* number to the line. Uses T_GLOBAL_DEBUGGING_LEVEL to control whether it is
|
||||
* turned on or off.
|
||||
*
|
||||
* @param format_string
|
||||
*/
|
||||
#if T_GLOBAL_DEBUGGING_LEVEL > 0
|
||||
#define T_DEBUG(format_string, ...) \
|
||||
if (T_GLOBAL_DEBUGGING_LEVEL > 0) { \
|
||||
fprintf(stderr, "[%s,%d] " format_string " \n", __FILE__, __LINE__, ##__VA_ARGS__); \
|
||||
}
|
||||
#else
|
||||
#define T_DEBUG(format_string, ...)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* analogous to T_DEBUG but also prints the time
|
||||
*
|
||||
* @param string format_string input: printf style format string
|
||||
*/
|
||||
#if T_GLOBAL_DEBUGGING_LEVEL > 0
|
||||
#define T_DEBUG_T(format_string, ...) \
|
||||
{ \
|
||||
if (T_GLOBAL_DEBUGGING_LEVEL > 0) { \
|
||||
time_t now; \
|
||||
char dbgtime[26]; \
|
||||
time(&now); \
|
||||
THRIFT_CTIME_R(&now, dbgtime); \
|
||||
dbgtime[24] = '\0'; \
|
||||
fprintf(stderr, \
|
||||
"[%s,%d] [%s] " format_string " \n", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
dbgtime, \
|
||||
##__VA_ARGS__); \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define T_DEBUG_T(format_string, ...)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* analogous to T_DEBUG but uses input level to determine whether or not the string
|
||||
* should be logged.
|
||||
*
|
||||
* @param int level: specified debug level
|
||||
* @param string format_string input: format string
|
||||
*/
|
||||
#define T_DEBUG_L(level, format_string, ...) \
|
||||
if ((level) > 0) { \
|
||||
fprintf(stderr, "[%s,%d] " format_string " \n", __FILE__, __LINE__, ##__VA_ARGS__); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicit error logging. Prints time, file name and line number
|
||||
*
|
||||
* @param string format_string input: printf style format string
|
||||
*/
|
||||
#define T_ERROR(format_string, ...) \
|
||||
{ \
|
||||
time_t now; \
|
||||
char dbgtime[26]; \
|
||||
time(&now); \
|
||||
THRIFT_CTIME_R(&now, dbgtime); \
|
||||
dbgtime[24] = '\0'; \
|
||||
fprintf(stderr, \
|
||||
"[%s,%d] [%s] ERROR: " format_string " \n", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
dbgtime, \
|
||||
##__VA_ARGS__); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Analogous to T_ERROR, additionally aborting the process.
|
||||
* WARNING: macro calls abort(), ending program execution
|
||||
*
|
||||
* @param string format_string input: printf style format string
|
||||
*/
|
||||
#define T_ERROR_ABORT(format_string, ...) \
|
||||
{ \
|
||||
time_t now; \
|
||||
char dbgtime[26]; \
|
||||
time(&now); \
|
||||
THRIFT_CTIME_R(&now, dbgtime); \
|
||||
dbgtime[24] = '\0'; \
|
||||
fprintf(stderr, \
|
||||
"[%s,%d] [%s] ERROR: Going to abort " format_string " \n", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
dbgtime, \
|
||||
##__VA_ARGS__); \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Log input message
|
||||
*
|
||||
* @param string format_string input: printf style format string
|
||||
*/
|
||||
#if T_GLOBAL_LOGGING_LEVEL > 0
|
||||
#define T_LOG_OPER(format_string, ...) \
|
||||
{ \
|
||||
if (T_GLOBAL_LOGGING_LEVEL > 0) { \
|
||||
time_t now; \
|
||||
char dbgtime[26]; \
|
||||
time(&now); \
|
||||
THRIFT_CTIME_R(&now, dbgtime); \
|
||||
dbgtime[24] = '\0'; \
|
||||
fprintf(stderr, "[%s] " format_string " \n", dbgtime, ##__VA_ARGS__); \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define T_LOG_OPER(format_string, ...)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* T_GLOBAL_DEBUG_VIRTUAL = 0 or unset: normal operation,
|
||||
* virtual call debug messages disabled
|
||||
* T_GLOBAL_DEBUG_VIRTUAL = 1: log a debug messages whenever an
|
||||
* avoidable virtual call is made
|
||||
* T_GLOBAL_DEBUG_VIRTUAL = 2: record detailed info that can be
|
||||
* printed by calling
|
||||
* apache::thrift::profile_print_info()
|
||||
*/
|
||||
#if T_GLOBAL_DEBUG_VIRTUAL > 1
|
||||
#define T_VIRTUAL_CALL() ::apache::thrift::profile_virtual_call(typeid(*this))
|
||||
#define T_GENERIC_PROTOCOL(template_class, generic_prot, specific_prot) \
|
||||
do { \
|
||||
if (!(specific_prot)) { \
|
||||
::apache::thrift::profile_generic_protocol(typeid(*template_class), typeid(*generic_prot)); \
|
||||
} \
|
||||
} while (0)
|
||||
#elif T_GLOBAL_DEBUG_VIRTUAL == 1
|
||||
#define T_VIRTUAL_CALL() fprintf(stderr, "[%s,%d] virtual call\n", __FILE__, __LINE__)
|
||||
#define T_GENERIC_PROTOCOL(template_class, generic_prot, specific_prot) \
|
||||
do { \
|
||||
if (!(specific_prot)) { \
|
||||
fprintf(stderr, "[%s,%d] failed to cast to specific protocol type\n", __FILE__, __LINE__); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define T_VIRTUAL_CALL()
|
||||
#define T_GENERIC_PROTOCOL(template_class, generic_prot, specific_prot)
|
||||
#endif
|
||||
|
||||
#endif // #ifndef _THRIFT_TLOGGING_H_
|
126
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/TOutput.cpp
generated
vendored
Normal file
126
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/TOutput.cpp
generated
vendored
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/Thrift.h>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
|
||||
TOutput GlobalOutput;
|
||||
|
||||
void TOutput::printf(const char* message, ...) {
|
||||
#ifndef THRIFT_SQUELCH_CONSOLE_OUTPUT
|
||||
// Try to reduce heap usage, even if printf is called rarely.
|
||||
static const int STACK_BUF_SIZE = 256;
|
||||
char stack_buf[STACK_BUF_SIZE];
|
||||
va_list ap;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
va_start(ap, message);
|
||||
int need = _vscprintf(message, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (need < STACK_BUF_SIZE) {
|
||||
va_start(ap, message);
|
||||
vsnprintf_s(stack_buf, STACK_BUF_SIZE, _TRUNCATE, message, ap);
|
||||
va_end(ap);
|
||||
f_(stack_buf);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
va_start(ap, message);
|
||||
int need = vsnprintf(stack_buf, STACK_BUF_SIZE, message, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (need < STACK_BUF_SIZE) {
|
||||
f_(stack_buf);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
char* heap_buf = (char*)malloc((need + 1) * sizeof(char));
|
||||
if (heap_buf == NULL) {
|
||||
#ifdef _MSC_VER
|
||||
va_start(ap, message);
|
||||
vsnprintf_s(stack_buf, STACK_BUF_SIZE, _TRUNCATE, message, ap);
|
||||
va_end(ap);
|
||||
#endif
|
||||
// Malloc failed. We might as well print the stack buffer.
|
||||
f_(stack_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
va_start(ap, message);
|
||||
int rval = vsnprintf(heap_buf, need + 1, message, ap);
|
||||
va_end(ap);
|
||||
// TODO(shigin): inform user
|
||||
if (rval != -1) {
|
||||
f_(heap_buf);
|
||||
}
|
||||
free(heap_buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
void TOutput::errorTimeWrapper(const char* msg) {
|
||||
#ifndef THRIFT_SQUELCH_CONSOLE_OUTPUT
|
||||
time_t now;
|
||||
char dbgtime[26];
|
||||
time(&now);
|
||||
THRIFT_CTIME_R(&now, dbgtime);
|
||||
dbgtime[24] = 0;
|
||||
fprintf(stderr, "Thrift: %s %s\n", dbgtime, msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
void TOutput::perror(const char* message, int errno_copy) {
|
||||
std::string out = message + strerror_s(errno_copy);
|
||||
f_(out.c_str());
|
||||
}
|
||||
|
||||
std::string TOutput::strerror_s(int errno_copy) {
|
||||
#ifndef HAVE_STRERROR_R
|
||||
return "errno = " + boost::lexical_cast<std::string>(errno_copy);
|
||||
#else // HAVE_STRERROR_R
|
||||
|
||||
char b_errbuf[1024] = {'\0'};
|
||||
#ifdef STRERROR_R_CHAR_P
|
||||
char* b_error = strerror_r(errno_copy, b_errbuf, sizeof(b_errbuf));
|
||||
#else
|
||||
char* b_error = b_errbuf;
|
||||
int rv = strerror_r(errno_copy, b_errbuf, sizeof(b_errbuf));
|
||||
if (rv == -1) {
|
||||
// strerror_r failed. omgwtfbbq.
|
||||
return "XSI-compliant strerror_r() failed with errno = "
|
||||
+ boost::lexical_cast<std::string>(errno_copy);
|
||||
}
|
||||
#endif
|
||||
// Can anyone prove that explicit cast is probably not necessary
|
||||
// to ensure that the string object is constructed before
|
||||
// b_error becomes invalid?
|
||||
return std::string(b_error);
|
||||
|
||||
#endif // HAVE_STRERROR_R
|
||||
}
|
||||
}
|
||||
} // apache::thrift
|
58
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/TOutput.h
generated
vendored
Normal file
58
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/TOutput.h
generated
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_OUTPUT_H_
|
||||
#define _THRIFT_OUTPUT_H_ 1
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
|
||||
class TOutput {
|
||||
public:
|
||||
TOutput() : f_(&errorTimeWrapper) {}
|
||||
|
||||
inline void setOutputFunction(void (*function)(const char*)) { f_ = function; }
|
||||
|
||||
inline void operator()(const char* message) { f_(message); }
|
||||
|
||||
// It is important to have a const char* overload here instead of
|
||||
// just the string version, otherwise errno could be corrupted
|
||||
// if there is some problem allocating memory when constructing
|
||||
// the string.
|
||||
void perror(const char* message, int errno_copy);
|
||||
inline void perror(const std::string& message, int errno_copy) {
|
||||
perror(message.c_str(), errno_copy);
|
||||
}
|
||||
|
||||
void printf(const char* message, ...);
|
||||
|
||||
static void errorTimeWrapper(const char* msg);
|
||||
|
||||
/** Just like strerror_r but returns a C++ string object. */
|
||||
static std::string strerror_s(int errno_copy);
|
||||
|
||||
private:
|
||||
void (*f_)(const char*);
|
||||
};
|
||||
|
||||
extern TOutput GlobalOutput;
|
||||
}
|
||||
} // namespace apache::thrift
|
||||
|
||||
#endif //_THRIFT_OUTPUT_H_
|
230
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/TProcessor.h
generated
vendored
Normal file
230
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/TProcessor.h
generated
vendored
Normal file
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_TPROCESSOR_H_
|
||||
#define _THRIFT_TPROCESSOR_H_ 1
|
||||
|
||||
#include <string>
|
||||
#include <thrift/protocol/TProtocol.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
|
||||
/**
|
||||
* Virtual interface class that can handle events from the processor. To
|
||||
* use this you should subclass it and implement the methods that you care
|
||||
* about. Your subclass can also store local data that you may care about,
|
||||
* such as additional "arguments" to these methods (stored in the object
|
||||
* instance's state).
|
||||
*/
|
||||
class TProcessorEventHandler {
|
||||
public:
|
||||
virtual ~TProcessorEventHandler() {}
|
||||
|
||||
/**
|
||||
* Called before calling other callback methods.
|
||||
* Expected to return some sort of context object.
|
||||
* The return value is passed to all other callbacks
|
||||
* for that function invocation.
|
||||
*/
|
||||
virtual void* getContext(const char* fn_name, void* serverContext) {
|
||||
(void)fn_name;
|
||||
(void)serverContext;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expected to free resources associated with a context.
|
||||
*/
|
||||
virtual void freeContext(void* ctx, const char* fn_name) {
|
||||
(void)ctx;
|
||||
(void)fn_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called before reading arguments.
|
||||
*/
|
||||
virtual void preRead(void* ctx, const char* fn_name) {
|
||||
(void)ctx;
|
||||
(void)fn_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called between reading arguments and calling the handler.
|
||||
*/
|
||||
virtual void postRead(void* ctx, const char* fn_name, uint32_t bytes) {
|
||||
(void)ctx;
|
||||
(void)fn_name;
|
||||
(void)bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called between calling the handler and writing the response.
|
||||
*/
|
||||
virtual void preWrite(void* ctx, const char* fn_name) {
|
||||
(void)ctx;
|
||||
(void)fn_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after writing the response.
|
||||
*/
|
||||
virtual void postWrite(void* ctx, const char* fn_name, uint32_t bytes) {
|
||||
(void)ctx;
|
||||
(void)fn_name;
|
||||
(void)bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an async function call completes successfully.
|
||||
*/
|
||||
virtual void asyncComplete(void* ctx, const char* fn_name) {
|
||||
(void)ctx;
|
||||
(void)fn_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called if the handler throws an undeclared exception.
|
||||
*/
|
||||
virtual void handlerError(void* ctx, const char* fn_name) {
|
||||
(void)ctx;
|
||||
(void)fn_name;
|
||||
}
|
||||
|
||||
protected:
|
||||
TProcessorEventHandler() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* A helper class used by the generated code to free each context.
|
||||
*/
|
||||
class TProcessorContextFreer {
|
||||
public:
|
||||
TProcessorContextFreer(TProcessorEventHandler* handler, void* context, const char* method)
|
||||
: handler_(handler), context_(context), method_(method) {}
|
||||
~TProcessorContextFreer() {
|
||||
if (handler_ != NULL)
|
||||
handler_->freeContext(context_, method_);
|
||||
}
|
||||
void unregister() { handler_ = NULL; }
|
||||
|
||||
private:
|
||||
apache::thrift::TProcessorEventHandler* handler_;
|
||||
void* context_;
|
||||
const char* method_;
|
||||
};
|
||||
|
||||
/**
|
||||
* A processor is a generic object that acts upon two streams of data, one
|
||||
* an input and the other an output. The definition of this object is loose,
|
||||
* though the typical case is for some sort of server that either generates
|
||||
* responses to an input stream or forwards data from one pipe onto another.
|
||||
*
|
||||
*/
|
||||
class TProcessor {
|
||||
public:
|
||||
virtual ~TProcessor() {}
|
||||
|
||||
virtual bool process(boost::shared_ptr<protocol::TProtocol> in,
|
||||
boost::shared_ptr<protocol::TProtocol> out,
|
||||
void* connectionContext) = 0;
|
||||
|
||||
bool process(boost::shared_ptr<apache::thrift::protocol::TProtocol> io, void* connectionContext) {
|
||||
return process(io, io, connectionContext);
|
||||
}
|
||||
|
||||
boost::shared_ptr<TProcessorEventHandler> getEventHandler() const { return eventHandler_; }
|
||||
|
||||
void setEventHandler(boost::shared_ptr<TProcessorEventHandler> eventHandler) {
|
||||
eventHandler_ = eventHandler;
|
||||
}
|
||||
|
||||
protected:
|
||||
TProcessor() {}
|
||||
|
||||
boost::shared_ptr<TProcessorEventHandler> eventHandler_;
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a helper class to allow boost::shared_ptr to be used with handler
|
||||
* pointers returned by the generated handler factories.
|
||||
*
|
||||
* The handler factory classes generated by the thrift compiler return raw
|
||||
* pointers, and factory->releaseHandler() must be called when the handler is
|
||||
* no longer needed.
|
||||
*
|
||||
* A ReleaseHandler object can be instantiated and passed as the second
|
||||
* parameter to a shared_ptr, so that factory->releaseHandler() will be called
|
||||
* when the object is no longer needed, instead of deleting the pointer.
|
||||
*/
|
||||
template <typename HandlerFactory_>
|
||||
class ReleaseHandler {
|
||||
public:
|
||||
ReleaseHandler(const boost::shared_ptr<HandlerFactory_>& handlerFactory)
|
||||
: handlerFactory_(handlerFactory) {}
|
||||
|
||||
void operator()(typename HandlerFactory_::Handler* handler) {
|
||||
if (handler) {
|
||||
handlerFactory_->releaseHandler(handler);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
boost::shared_ptr<HandlerFactory_> handlerFactory_;
|
||||
};
|
||||
|
||||
struct TConnectionInfo {
|
||||
// The input and output protocols
|
||||
boost::shared_ptr<protocol::TProtocol> input;
|
||||
boost::shared_ptr<protocol::TProtocol> output;
|
||||
// The underlying transport used for the connection
|
||||
// This is the transport that was returned by TServerTransport::accept(),
|
||||
// and it may be different than the transport pointed to by the input and
|
||||
// output protocols.
|
||||
boost::shared_ptr<transport::TTransport> transport;
|
||||
};
|
||||
|
||||
class TProcessorFactory {
|
||||
public:
|
||||
virtual ~TProcessorFactory() {}
|
||||
|
||||
/**
|
||||
* Get the TProcessor to use for a particular connection.
|
||||
*
|
||||
* This method is always invoked in the same thread that the connection was
|
||||
* accepted on. This generally means that this call does not need to be
|
||||
* thread safe, as it will always be invoked from a single thread.
|
||||
*/
|
||||
virtual boost::shared_ptr<TProcessor> getProcessor(const TConnectionInfo& connInfo) = 0;
|
||||
};
|
||||
|
||||
class TSingletonProcessorFactory : public TProcessorFactory {
|
||||
public:
|
||||
TSingletonProcessorFactory(boost::shared_ptr<TProcessor> processor) : processor_(processor) {}
|
||||
|
||||
boost::shared_ptr<TProcessor> getProcessor(const TConnectionInfo&) { return processor_; }
|
||||
|
||||
private:
|
||||
boost::shared_ptr<TProcessor> processor_;
|
||||
};
|
||||
}
|
||||
} // apache::thrift
|
||||
|
||||
#endif // #ifndef _THRIFT_TPROCESSOR_H_
|
89
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/TToString.h
generated
vendored
Normal file
89
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/TToString.h
generated
vendored
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_TOSTRING_H_
|
||||
#define _THRIFT_TOSTRING_H_ 1
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
|
||||
template <typename T>
|
||||
std::string to_string(const T& t) {
|
||||
return boost::lexical_cast<std::string>(t);
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
std::string to_string(const std::map<K, V>& m);
|
||||
|
||||
template <typename T>
|
||||
std::string to_string(const std::set<T>& s);
|
||||
|
||||
template <typename T>
|
||||
std::string to_string(const std::vector<T>& t);
|
||||
|
||||
template <typename K, typename V>
|
||||
std::string to_string(const typename std::pair<K, V>& v) {
|
||||
std::ostringstream o;
|
||||
o << to_string(v.first) << ": " << to_string(v.second);
|
||||
return o.str();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string to_string(const T& beg, const T& end) {
|
||||
std::ostringstream o;
|
||||
for (T it = beg; it != end; ++it) {
|
||||
if (it != beg)
|
||||
o << ", ";
|
||||
o << to_string(*it);
|
||||
}
|
||||
return o.str();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string to_string(const std::vector<T>& t) {
|
||||
std::ostringstream o;
|
||||
o << "[" << to_string(t.begin(), t.end()) << "]";
|
||||
return o.str();
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
std::string to_string(const std::map<K, V>& m) {
|
||||
std::ostringstream o;
|
||||
o << "{" << to_string(m.begin(), m.end()) << "}";
|
||||
return o.str();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string to_string(const std::set<T>& s) {
|
||||
std::ostringstream o;
|
||||
o << "{" << to_string(s.begin(), s.end()) << "}";
|
||||
return o.str();
|
||||
}
|
||||
}
|
||||
} // apache::thrift
|
||||
|
||||
#endif // _THRIFT_TOSTRING_H_
|
136
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/Thrift.h
generated
vendored
Normal file
136
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/Thrift.h
generated
vendored
Normal file
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_THRIFT_H_
|
||||
#define _THRIFT_THRIFT_H_ 1
|
||||
|
||||
#include <thrift/transport/PlatformSocket.h>
|
||||
|
||||
#include <thrift/thrift-config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <exception>
|
||||
#include <typeinfo>
|
||||
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
#include <thrift/TLogging.h>
|
||||
#include <thrift/TOutput.h>
|
||||
|
||||
#define THRIFT_UNUSED_VARIABLE(x) ((void)(x))
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
|
||||
class TEnumIterator
|
||||
: public std::iterator<std::forward_iterator_tag, std::pair<int, const char*> > {
|
||||
public:
|
||||
TEnumIterator(int n, int* enums, const char** names)
|
||||
: ii_(0), n_(n), enums_(enums), names_(names) {}
|
||||
|
||||
int operator++() { return ++ii_; }
|
||||
|
||||
bool operator!=(const TEnumIterator& end) {
|
||||
THRIFT_UNUSED_VARIABLE(end);
|
||||
assert(end.n_ == -1);
|
||||
return (ii_ != n_);
|
||||
}
|
||||
|
||||
std::pair<int, const char*> operator*() const { return std::make_pair(enums_[ii_], names_[ii_]); }
|
||||
|
||||
private:
|
||||
int ii_;
|
||||
const int n_;
|
||||
int* enums_;
|
||||
const char** names_;
|
||||
};
|
||||
|
||||
class TException : public std::exception {
|
||||
public:
|
||||
TException() : message_() {}
|
||||
|
||||
TException(const std::string& message) : message_(message) {}
|
||||
|
||||
virtual ~TException() throw() {}
|
||||
|
||||
virtual const char* what() const throw() {
|
||||
if (message_.empty()) {
|
||||
return "Default TException.";
|
||||
} else {
|
||||
return message_.c_str();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string message_;
|
||||
};
|
||||
|
||||
class TDelayedException {
|
||||
public:
|
||||
template <class E>
|
||||
static TDelayedException* delayException(const E& e);
|
||||
virtual void throw_it() = 0;
|
||||
virtual ~TDelayedException(){};
|
||||
};
|
||||
|
||||
template <class E>
|
||||
class TExceptionWrapper : public TDelayedException {
|
||||
public:
|
||||
TExceptionWrapper(const E& e) : e_(e) {}
|
||||
virtual void throw_it() {
|
||||
E temp(e_);
|
||||
delete this;
|
||||
throw temp;
|
||||
}
|
||||
|
||||
private:
|
||||
E e_;
|
||||
};
|
||||
|
||||
template <class E>
|
||||
TDelayedException* TDelayedException::delayException(const E& e) {
|
||||
return new TExceptionWrapper<E>(e);
|
||||
}
|
||||
|
||||
#if T_GLOBAL_DEBUG_VIRTUAL > 1
|
||||
void profile_virtual_call(const std::type_info& info);
|
||||
void profile_generic_protocol(const std::type_info& template_type, const std::type_info& prot_type);
|
||||
void profile_print_info(FILE* f);
|
||||
void profile_print_info();
|
||||
void profile_write_pprof(FILE* gen_calls_f, FILE* virtual_calls_f);
|
||||
#endif
|
||||
}
|
||||
} // apache::thrift
|
||||
|
||||
#endif // #ifndef _THRIFT_THRIFT_H_
|
425
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/VirtualProfiling.cpp
generated
vendored
Normal file
425
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/VirtualProfiling.cpp
generated
vendored
Normal file
|
@ -0,0 +1,425 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/Thrift.h>
|
||||
|
||||
// Do nothing if virtual call profiling is not enabled
|
||||
#if T_GLOBAL_DEBUG_VIRTUAL > 1
|
||||
|
||||
// TODO: This code only works with g++ (since we rely on the fact
|
||||
// that all std::type_info instances referring to a particular type
|
||||
// always return the exact same pointer value from name().)
|
||||
#ifndef __GNUG__
|
||||
#error "Thrift virtual function profiling currently only works with gcc"
|
||||
#endif // !__GNUG__
|
||||
|
||||
// TODO: We also require glibc for the backtrace() and backtrace_symbols()
|
||||
// functions.
|
||||
#ifndef __GLIBC__
|
||||
#error "Thrift virtual function profiling currently requires glibc"
|
||||
#endif // !__GLIBC__
|
||||
|
||||
#include <thrift/concurrency/Mutex.h>
|
||||
|
||||
#include <ext/hash_map>
|
||||
#include <execinfo.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
|
||||
using ::apache::thrift::concurrency::Mutex;
|
||||
using ::apache::thrift::concurrency::Guard;
|
||||
|
||||
static const unsigned int MAX_STACK_DEPTH = 15;
|
||||
|
||||
/**
|
||||
* A stack trace
|
||||
*/
|
||||
class Backtrace {
|
||||
public:
|
||||
Backtrace(int skip = 0);
|
||||
Backtrace(Backtrace const& bt);
|
||||
|
||||
void operator=(Backtrace const& bt) {
|
||||
numCallers_ = bt.numCallers_;
|
||||
if (numCallers_ >= 0) {
|
||||
memcpy(callers_, bt.callers_, numCallers_ * sizeof(void*));
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(Backtrace const& bt) const { return (cmp(bt) == 0); }
|
||||
|
||||
size_t hash() const {
|
||||
intptr_t ret = 0;
|
||||
for (int n = 0; n < numCallers_; ++n) {
|
||||
ret ^= reinterpret_cast<intptr_t>(callers_[n]);
|
||||
}
|
||||
return static_cast<size_t>(ret);
|
||||
}
|
||||
|
||||
int cmp(Backtrace const& bt) const {
|
||||
int depth_diff = (numCallers_ - bt.numCallers_);
|
||||
if (depth_diff != 0) {
|
||||
return depth_diff;
|
||||
}
|
||||
|
||||
for (int n = 0; n < numCallers_; ++n) {
|
||||
int diff = reinterpret_cast<intptr_t>(callers_[n])
|
||||
- reinterpret_cast<intptr_t>(bt.callers_[n]);
|
||||
if (diff != 0) {
|
||||
return diff;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print(FILE* f, int indent = 0, int start = 0) const {
|
||||
char** strings = backtrace_symbols(callers_, numCallers_);
|
||||
if (strings) {
|
||||
start += skip_;
|
||||
if (start < 0) {
|
||||
start = 0;
|
||||
}
|
||||
for (int n = start; n < numCallers_; ++n) {
|
||||
fprintf(f, "%*s#%-2d %s\n", indent, "", n, strings[n]);
|
||||
}
|
||||
free(strings);
|
||||
} else {
|
||||
fprintf(f, "%*s<failed to determine symbols>\n", indent, "");
|
||||
}
|
||||
}
|
||||
|
||||
int getDepth() const { return numCallers_ - skip_; }
|
||||
|
||||
void* getFrame(int index) const {
|
||||
int adjusted_index = index + skip_;
|
||||
if (adjusted_index < 0 || adjusted_index >= numCallers_) {
|
||||
return NULL;
|
||||
}
|
||||
return callers_[adjusted_index];
|
||||
}
|
||||
|
||||
private:
|
||||
void* callers_[MAX_STACK_DEPTH];
|
||||
int numCallers_;
|
||||
int skip_;
|
||||
};
|
||||
|
||||
// Define the constructors non-inline, so they consistently add a single
|
||||
// frame to the stack trace, regardless of whether optimization is enabled
|
||||
Backtrace::Backtrace(int skip)
|
||||
: skip_(skip + 1) // ignore the constructor itself
|
||||
{
|
||||
numCallers_ = backtrace(callers_, MAX_STACK_DEPTH);
|
||||
if (skip_ > numCallers_) {
|
||||
skip_ = numCallers_;
|
||||
}
|
||||
}
|
||||
|
||||
Backtrace::Backtrace(Backtrace const& bt) : numCallers_(bt.numCallers_), skip_(bt.skip_) {
|
||||
if (numCallers_ >= 0) {
|
||||
memcpy(callers_, bt.callers_, numCallers_ * sizeof(void*));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A backtrace, plus one or two type names
|
||||
*/
|
||||
class Key {
|
||||
public:
|
||||
class Hash {
|
||||
public:
|
||||
size_t operator()(Key const& k) const { return k.hash(); }
|
||||
};
|
||||
|
||||
Key(const Backtrace* bt, const std::type_info& type_info)
|
||||
: backtrace_(bt), typeName1_(type_info.name()), typeName2_(NULL) {}
|
||||
|
||||
Key(const Backtrace* bt, const std::type_info& type_info1, const std::type_info& type_info2)
|
||||
: backtrace_(bt), typeName1_(type_info1.name()), typeName2_(type_info2.name()) {}
|
||||
|
||||
Key(const Key& k)
|
||||
: backtrace_(k.backtrace_), typeName1_(k.typeName1_), typeName2_(k.typeName2_) {}
|
||||
|
||||
void operator=(const Key& k) {
|
||||
backtrace_ = k.backtrace_;
|
||||
typeName1_ = k.typeName1_;
|
||||
typeName2_ = k.typeName2_;
|
||||
}
|
||||
|
||||
const Backtrace* getBacktrace() const { return backtrace_; }
|
||||
|
||||
const char* getTypeName() const { return typeName1_; }
|
||||
|
||||
const char* getTypeName2() const { return typeName2_; }
|
||||
|
||||
void makePersistent() {
|
||||
// Copy the Backtrace object
|
||||
backtrace_ = new Backtrace(*backtrace_);
|
||||
|
||||
// NOTE: We don't copy the type name.
|
||||
// The GNU libstdc++ implementation of type_info::name() returns a value
|
||||
// that will be valid for the lifetime of the program. (Although the C++
|
||||
// standard doesn't guarantee this will be true on all implementations.)
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up memory allocated by makePersistent()
|
||||
*
|
||||
* Should only be invoked if makePersistent() has previously been called.
|
||||
* The Key should no longer be used after cleanup() is called.
|
||||
*/
|
||||
void cleanup() {
|
||||
delete backtrace_;
|
||||
backtrace_ = NULL;
|
||||
}
|
||||
|
||||
int cmp(const Key& k) const {
|
||||
int ret = backtrace_->cmp(*k.backtrace_);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// NOTE: We compare just the name pointers.
|
||||
// With GNU libstdc++, every type_info object for the same type points to
|
||||
// exactly the same name string. (Although this isn't guaranteed by the
|
||||
// C++ standard.)
|
||||
ret = k.typeName1_ - typeName1_;
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
return k.typeName2_ - typeName2_;
|
||||
}
|
||||
|
||||
bool operator==(const Key& k) const { return cmp(k) == 0; }
|
||||
|
||||
size_t hash() const {
|
||||
// NOTE: As above, we just use the name pointer value.
|
||||
// Works with GNU libstdc++, but not guaranteed to be correct on all
|
||||
// implementations.
|
||||
return backtrace_->hash() ^ reinterpret_cast<size_t>(typeName1_)
|
||||
^ reinterpret_cast<size_t>(typeName2_);
|
||||
}
|
||||
|
||||
private:
|
||||
const Backtrace* backtrace_;
|
||||
const char* typeName1_;
|
||||
const char* typeName2_;
|
||||
};
|
||||
|
||||
/**
|
||||
* A functor that determines which of two BacktraceMap entries
|
||||
* has a higher count.
|
||||
*/
|
||||
class CountGreater {
|
||||
public:
|
||||
bool operator()(std::pair<Key, size_t> bt1, std::pair<Key, size_t> bt2) const {
|
||||
return bt1.second > bt2.second;
|
||||
}
|
||||
};
|
||||
|
||||
typedef __gnu_cxx::hash_map<Key, size_t, Key::Hash> BacktraceMap;
|
||||
|
||||
/**
|
||||
* A map describing how many times T_VIRTUAL_CALL() has been invoked.
|
||||
*/
|
||||
BacktraceMap virtual_calls;
|
||||
Mutex virtual_calls_mutex;
|
||||
|
||||
/**
|
||||
* A map describing how many times T_GENERIC_PROTOCOL() has been invoked.
|
||||
*/
|
||||
BacktraceMap generic_calls;
|
||||
Mutex generic_calls_mutex;
|
||||
|
||||
void _record_backtrace(BacktraceMap* map, const Mutex& mutex, Key* k) {
|
||||
Guard guard(mutex);
|
||||
|
||||
BacktraceMap::iterator it = map->find(*k);
|
||||
if (it == map->end()) {
|
||||
k->makePersistent();
|
||||
map->insert(std::make_pair(*k, 1));
|
||||
} else {
|
||||
// increment the count
|
||||
// NOTE: we could assert if it->second is 0 afterwards, since that would
|
||||
// mean we've wrapped.
|
||||
++(it->second);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Record an unnecessary virtual function call.
|
||||
*
|
||||
* This method is invoked by the T_VIRTUAL_CALL() macro.
|
||||
*/
|
||||
void profile_virtual_call(const std::type_info& type) {
|
||||
int const skip = 1; // ignore this frame
|
||||
Backtrace bt(skip);
|
||||
Key k(&bt, type);
|
||||
_record_backtrace(&virtual_calls, virtual_calls_mutex, &k);
|
||||
}
|
||||
|
||||
/**
|
||||
* Record a call to a template processor with a protocol that is not the one
|
||||
* specified in the template parameter.
|
||||
*
|
||||
* This method is invoked by the T_GENERIC_PROTOCOL() macro.
|
||||
*/
|
||||
void profile_generic_protocol(const std::type_info& template_type,
|
||||
const std::type_info& prot_type) {
|
||||
int const skip = 1; // ignore this frame
|
||||
Backtrace bt(skip);
|
||||
Key k(&bt, template_type, prot_type);
|
||||
_record_backtrace(&generic_calls, generic_calls_mutex, &k);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the recorded profiling information to the specified file.
|
||||
*/
|
||||
void profile_print_info(FILE* f) {
|
||||
typedef std::vector<std::pair<Key, size_t> > BacktraceVector;
|
||||
|
||||
CountGreater is_greater;
|
||||
|
||||
// Grab both locks for the duration of the print operation,
|
||||
// to ensure the output is a consistent snapshot of a single point in time
|
||||
Guard generic_calls_guard(generic_calls_mutex);
|
||||
Guard virtual_calls_guard(virtual_calls_mutex);
|
||||
|
||||
// print the info from generic_calls, sorted by frequency
|
||||
//
|
||||
// We print the generic_calls info ahead of virtual_calls, since it is more
|
||||
// useful in some cases. All T_GENERIC_PROTOCOL calls can be eliminated
|
||||
// from most programs. Not all T_VIRTUAL_CALLs will be eliminated by
|
||||
// converting to templates.
|
||||
BacktraceVector gp_sorted(generic_calls.begin(), generic_calls.end());
|
||||
std::sort(gp_sorted.begin(), gp_sorted.end(), is_greater);
|
||||
|
||||
for (BacktraceVector::const_iterator it = gp_sorted.begin(); it != gp_sorted.end(); ++it) {
|
||||
Key const& key = it->first;
|
||||
size_t const count = it->second;
|
||||
fprintf(f,
|
||||
"T_GENERIC_PROTOCOL: %zu calls to %s with a %s:\n",
|
||||
count,
|
||||
key.getTypeName(),
|
||||
key.getTypeName2());
|
||||
key.getBacktrace()->print(f, 2);
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
||||
// print the info from virtual_calls, sorted by frequency
|
||||
BacktraceVector vc_sorted(virtual_calls.begin(), virtual_calls.end());
|
||||
std::sort(vc_sorted.begin(), vc_sorted.end(), is_greater);
|
||||
|
||||
for (BacktraceVector::const_iterator it = vc_sorted.begin(); it != vc_sorted.end(); ++it) {
|
||||
Key const& key = it->first;
|
||||
size_t const count = it->second;
|
||||
fprintf(f, "T_VIRTUAL_CALL: %zu calls on %s:\n", count, key.getTypeName());
|
||||
key.getBacktrace()->print(f, 2);
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the recorded profiling information to stdout.
|
||||
*/
|
||||
void profile_print_info() {
|
||||
profile_print_info(stdout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a BacktraceMap as Google CPU profiler binary data.
|
||||
*/
|
||||
static void profile_write_pprof_file(FILE* f, BacktraceMap const& map) {
|
||||
// Write the header
|
||||
uintptr_t header[5] = {0, 3, 0, 0, 0};
|
||||
fwrite(&header, sizeof(header), 1, f);
|
||||
|
||||
// Write the profile records
|
||||
for (BacktraceMap::const_iterator it = map.begin(); it != map.end(); ++it) {
|
||||
uintptr_t count = it->second;
|
||||
fwrite(&count, sizeof(count), 1, f);
|
||||
|
||||
Backtrace const* bt = it->first.getBacktrace();
|
||||
uintptr_t num_pcs = bt->getDepth();
|
||||
fwrite(&num_pcs, sizeof(num_pcs), 1, f);
|
||||
|
||||
for (uintptr_t n = 0; n < num_pcs; ++n) {
|
||||
void* pc = bt->getFrame(n);
|
||||
fwrite(&pc, sizeof(pc), 1, f);
|
||||
}
|
||||
}
|
||||
|
||||
// Write the trailer
|
||||
uintptr_t trailer[3] = {0, 1, 0};
|
||||
fwrite(&trailer, sizeof(trailer), 1, f);
|
||||
|
||||
// Write /proc/self/maps
|
||||
// TODO(simpkins): This only works on linux
|
||||
FILE* proc_maps = fopen("/proc/self/maps", "r");
|
||||
if (proc_maps) {
|
||||
uint8_t buf[4096];
|
||||
while (true) {
|
||||
size_t bytes_read = fread(buf, 1, sizeof(buf), proc_maps);
|
||||
if (bytes_read == 0) {
|
||||
break;
|
||||
}
|
||||
fwrite(buf, 1, bytes_read, f);
|
||||
}
|
||||
fclose(proc_maps);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the recorded profiling information as pprof files.
|
||||
*
|
||||
* This writes the information using the Google CPU profiler binary data
|
||||
* format, so it can be analyzed with pprof. Note that information about the
|
||||
* protocol/transport data types cannot be stored in this file format.
|
||||
*
|
||||
* See http://code.google.com/p/google-perftools/ for more details.
|
||||
*
|
||||
* @param gen_calls_f The information about calls to
|
||||
* profile_generic_protocol() will be written to this
|
||||
* file.
|
||||
* @param virtual_calls_f The information about calls to
|
||||
* profile_virtual_call() will be written to this file.
|
||||
*/
|
||||
void profile_write_pprof(FILE* gen_calls_f, FILE* virtual_calls_f) {
|
||||
typedef std::vector<std::pair<Key, size_t> > BacktraceVector;
|
||||
|
||||
CountGreater is_greater;
|
||||
|
||||
// Grab both locks for the duration of the print operation,
|
||||
// to ensure the output is a consistent snapshot of a single point in time
|
||||
Guard generic_calls_guard(generic_calls_mutex);
|
||||
Guard virtual_calls_guard(virtual_calls_mutex);
|
||||
|
||||
// write the info from generic_calls
|
||||
profile_write_pprof_file(gen_calls_f, generic_calls);
|
||||
|
||||
// write the info from virtual_calls
|
||||
profile_write_pprof_file(virtual_calls_f, virtual_calls);
|
||||
}
|
||||
}
|
||||
} // apache::thrift
|
||||
|
||||
#endif // T_GLOBAL_PROFILE_VIRTUAL > 0
|
48
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TAsyncBufferProcessor.h
generated
vendored
Normal file
48
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TAsyncBufferProcessor.h
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_TASYNC_BUFFER_PROCESSOR_H_
|
||||
#define _THRIFT_TASYNC_BUFFER_PROCESSOR_H_ 1
|
||||
|
||||
#include <thrift/cxxfunctional.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <thrift/transport/TBufferTransports.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace async {
|
||||
|
||||
class TAsyncBufferProcessor {
|
||||
public:
|
||||
// Process data in "in", putting the result in "out".
|
||||
// Call _return(true) when done, or _return(false) to
|
||||
// forcefully close the connection (if applicable).
|
||||
// "in" and "out" should be TMemoryBuffer or similar,
|
||||
// not a wrapper around a socket.
|
||||
virtual void process(apache::thrift::stdcxx::function<void(bool healthy)> _return,
|
||||
boost::shared_ptr<apache::thrift::transport::TBufferBase> ibuf,
|
||||
boost::shared_ptr<apache::thrift::transport::TBufferBase> obuf) = 0;
|
||||
virtual ~TAsyncBufferProcessor() {}
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::async
|
||||
|
||||
#endif // #ifndef _THRIFT_TASYNC_BUFFER_PROCESSOR_H_
|
37
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TAsyncChannel.cpp
generated
vendored
Normal file
37
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TAsyncChannel.cpp
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/async/TAsyncChannel.h>
|
||||
#include <thrift/cxxfunctional.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace async {
|
||||
|
||||
void TAsyncChannel::sendAndRecvMessage(const VoidCallback& cob,
|
||||
TMemoryBuffer* sendBuf,
|
||||
TMemoryBuffer* recvBuf) {
|
||||
apache::thrift::stdcxx::function<void()> send_done
|
||||
= apache::thrift::stdcxx::bind(&TAsyncChannel::recvMessage, this, cob, recvBuf);
|
||||
|
||||
sendMessage(send_done, sendBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::async
|
73
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TAsyncChannel.h
generated
vendored
Normal file
73
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TAsyncChannel.h
generated
vendored
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_ASYNC_TASYNCCHANNEL_H_
|
||||
#define _THRIFT_ASYNC_TASYNCCHANNEL_H_ 1
|
||||
|
||||
#include <thrift/cxxfunctional.h>
|
||||
#include <thrift/Thrift.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace transport {
|
||||
class TMemoryBuffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace async {
|
||||
using apache::thrift::transport::TMemoryBuffer;
|
||||
|
||||
class TAsyncChannel {
|
||||
public:
|
||||
typedef apache::thrift::stdcxx::function<void()> VoidCallback;
|
||||
|
||||
virtual ~TAsyncChannel() {}
|
||||
|
||||
// is the channel in a good state?
|
||||
virtual bool good() const = 0;
|
||||
virtual bool error() const = 0;
|
||||
virtual bool timedOut() const = 0;
|
||||
|
||||
/**
|
||||
* Send a message over the channel.
|
||||
*/
|
||||
virtual void sendMessage(const VoidCallback& cob,
|
||||
apache::thrift::transport::TMemoryBuffer* message) = 0;
|
||||
|
||||
/**
|
||||
* Receive a message from the channel.
|
||||
*/
|
||||
virtual void recvMessage(const VoidCallback& cob,
|
||||
apache::thrift::transport::TMemoryBuffer* message) = 0;
|
||||
|
||||
/**
|
||||
* Send a message over the channel and receive a response.
|
||||
*/
|
||||
virtual void sendAndRecvMessage(const VoidCallback& cob,
|
||||
apache::thrift::transport::TMemoryBuffer* sendBuf,
|
||||
apache::thrift::transport::TMemoryBuffer* recvBuf);
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::async
|
||||
|
||||
#endif // #ifndef _THRIFT_ASYNC_TASYNCCHANNEL_H_
|
151
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TAsyncDispatchProcessor.h
generated
vendored
Normal file
151
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TAsyncDispatchProcessor.h
generated
vendored
Normal file
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
#ifndef _THRIFT_ASYNC_TASYNCDISPATCHPROCESSOR_H_
|
||||
#define _THRIFT_ASYNC_TASYNCDISPATCHPROCESSOR_H_ 1
|
||||
|
||||
#include <thrift/async/TAsyncProcessor.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace async {
|
||||
|
||||
/**
|
||||
* TAsyncDispatchProcessor is a helper class to parse the message header then
|
||||
* call another function to dispatch based on the function name.
|
||||
*
|
||||
* Subclasses must implement dispatchCall() to dispatch on the function name.
|
||||
*/
|
||||
template <class Protocol_>
|
||||
class TAsyncDispatchProcessorT : public TAsyncProcessor {
|
||||
public:
|
||||
virtual void process(apache::thrift::stdcxx::function<void(bool success)> _return,
|
||||
boost::shared_ptr<protocol::TProtocol> in,
|
||||
boost::shared_ptr<protocol::TProtocol> out) {
|
||||
protocol::TProtocol* inRaw = in.get();
|
||||
protocol::TProtocol* outRaw = out.get();
|
||||
|
||||
// Try to dynamic cast to the template protocol type
|
||||
Protocol_* specificIn = dynamic_cast<Protocol_*>(inRaw);
|
||||
Protocol_* specificOut = dynamic_cast<Protocol_*>(outRaw);
|
||||
if (specificIn && specificOut) {
|
||||
return processFast(_return, specificIn, specificOut);
|
||||
}
|
||||
|
||||
// Log the fact that we have to use the slow path
|
||||
T_GENERIC_PROTOCOL(this, inRaw, specificIn);
|
||||
T_GENERIC_PROTOCOL(this, outRaw, specificOut);
|
||||
|
||||
std::string fname;
|
||||
protocol::TMessageType mtype;
|
||||
int32_t seqid;
|
||||
inRaw->readMessageBegin(fname, mtype, seqid);
|
||||
|
||||
// If this doesn't look like a valid call, log an error and return false so
|
||||
// that the server will close the connection.
|
||||
//
|
||||
// (The old generated processor code used to try to skip a T_STRUCT and
|
||||
// continue. However, that seems unsafe.)
|
||||
if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) {
|
||||
GlobalOutput.printf("received invalid message type %d from client", mtype);
|
||||
_return(false);
|
||||
return;
|
||||
}
|
||||
|
||||
return this->dispatchCall(_return, inRaw, outRaw, fname, seqid);
|
||||
}
|
||||
|
||||
void processFast(apache::thrift::stdcxx::function<void(bool success)> _return,
|
||||
Protocol_* in,
|
||||
Protocol_* out) {
|
||||
std::string fname;
|
||||
protocol::TMessageType mtype;
|
||||
int32_t seqid;
|
||||
in->readMessageBegin(fname, mtype, seqid);
|
||||
|
||||
if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) {
|
||||
GlobalOutput.printf("received invalid message type %d from client", mtype);
|
||||
_return(false);
|
||||
return;
|
||||
}
|
||||
|
||||
return this->dispatchCallTemplated(_return, in, out, fname, seqid);
|
||||
}
|
||||
|
||||
virtual void dispatchCall(apache::thrift::stdcxx::function<void(bool ok)> _return,
|
||||
apache::thrift::protocol::TProtocol* in,
|
||||
apache::thrift::protocol::TProtocol* out,
|
||||
const std::string& fname,
|
||||
int32_t seqid) = 0;
|
||||
|
||||
virtual void dispatchCallTemplated(apache::thrift::stdcxx::function<void(bool ok)> _return,
|
||||
Protocol_* in,
|
||||
Protocol_* out,
|
||||
const std::string& fname,
|
||||
int32_t seqid) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Non-templatized version of TAsyncDispatchProcessor,
|
||||
* that doesn't bother trying to perform a dynamic_cast.
|
||||
*/
|
||||
class TAsyncDispatchProcessor : public TAsyncProcessor {
|
||||
public:
|
||||
virtual void process(apache::thrift::stdcxx::function<void(bool success)> _return,
|
||||
boost::shared_ptr<protocol::TProtocol> in,
|
||||
boost::shared_ptr<protocol::TProtocol> out) {
|
||||
protocol::TProtocol* inRaw = in.get();
|
||||
protocol::TProtocol* outRaw = out.get();
|
||||
|
||||
std::string fname;
|
||||
protocol::TMessageType mtype;
|
||||
int32_t seqid;
|
||||
inRaw->readMessageBegin(fname, mtype, seqid);
|
||||
|
||||
// If this doesn't look like a valid call, log an error and return false so
|
||||
// that the server will close the connection.
|
||||
//
|
||||
// (The old generated processor code used to try to skip a T_STRUCT and
|
||||
// continue. However, that seems unsafe.)
|
||||
if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) {
|
||||
GlobalOutput.printf("received invalid message type %d from client", mtype);
|
||||
_return(false);
|
||||
return;
|
||||
}
|
||||
|
||||
return dispatchCall(_return, inRaw, outRaw, fname, seqid);
|
||||
}
|
||||
|
||||
virtual void dispatchCall(apache::thrift::stdcxx::function<void(bool ok)> _return,
|
||||
apache::thrift::protocol::TProtocol* in,
|
||||
apache::thrift::protocol::TProtocol* out,
|
||||
const std::string& fname,
|
||||
int32_t seqid) = 0;
|
||||
};
|
||||
|
||||
// Specialize TAsyncDispatchProcessorT for TProtocol and TDummyProtocol just to
|
||||
// use the generic TDispatchProcessor.
|
||||
template <>
|
||||
class TAsyncDispatchProcessorT<protocol::TDummyProtocol> : public TAsyncDispatchProcessor {};
|
||||
template <>
|
||||
class TAsyncDispatchProcessorT<protocol::TProtocol> : public TAsyncDispatchProcessor {};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::async
|
||||
|
||||
#endif // _THRIFT_ASYNC_TASYNCDISPATCHPROCESSOR_H_
|
86
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TAsyncProcessor.h
generated
vendored
Normal file
86
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TAsyncProcessor.h
generated
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_TASYNCPROCESSOR_H_
|
||||
#define _THRIFT_TASYNCPROCESSOR_H_ 1
|
||||
|
||||
#include <thrift/cxxfunctional.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <thrift/protocol/TProtocol.h>
|
||||
#include <thrift/TProcessor.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace async {
|
||||
|
||||
/**
|
||||
* Async version of a TProcessor. It is not expected to complete by the time
|
||||
* the call to process returns. Instead, it calls a cob to signal completion.
|
||||
*/
|
||||
|
||||
class TAsyncProcessor {
|
||||
public:
|
||||
virtual ~TAsyncProcessor() {}
|
||||
|
||||
virtual void process(apache::thrift::stdcxx::function<void(bool success)> _return,
|
||||
boost::shared_ptr<protocol::TProtocol> in,
|
||||
boost::shared_ptr<protocol::TProtocol> out) = 0;
|
||||
|
||||
void process(apache::thrift::stdcxx::function<void(bool success)> _return,
|
||||
boost::shared_ptr<apache::thrift::protocol::TProtocol> io) {
|
||||
return process(_return, io, io);
|
||||
}
|
||||
|
||||
boost::shared_ptr<TProcessorEventHandler> getEventHandler() const { return eventHandler_; }
|
||||
|
||||
void setEventHandler(boost::shared_ptr<TProcessorEventHandler> eventHandler) {
|
||||
eventHandler_ = eventHandler;
|
||||
}
|
||||
|
||||
protected:
|
||||
TAsyncProcessor() {}
|
||||
|
||||
boost::shared_ptr<TProcessorEventHandler> eventHandler_;
|
||||
};
|
||||
|
||||
class TAsyncProcessorFactory {
|
||||
public:
|
||||
virtual ~TAsyncProcessorFactory() {}
|
||||
|
||||
/**
|
||||
* Get the TAsyncProcessor to use for a particular connection.
|
||||
*
|
||||
* This method is always invoked in the same thread that the connection was
|
||||
* accepted on. This generally means that this call does not need to be
|
||||
* thread safe, as it will always be invoked from a single thread.
|
||||
*/
|
||||
virtual boost::shared_ptr<TAsyncProcessor> getProcessor(const TConnectionInfo& connInfo) = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::async
|
||||
|
||||
// XXX I'm lazy for now
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
using apache::thrift::async::TAsyncProcessor;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #ifndef _THRIFT_TASYNCPROCESSOR_H_
|
53
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TAsyncProtocolProcessor.cpp
generated
vendored
Normal file
53
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TAsyncProtocolProcessor.cpp
generated
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/async/TAsyncProtocolProcessor.h>
|
||||
|
||||
using apache::thrift::transport::TBufferBase;
|
||||
using apache::thrift::protocol::TProtocol;
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace async {
|
||||
|
||||
void TAsyncProtocolProcessor::process(apache::thrift::stdcxx::function<void(bool healthy)> _return,
|
||||
boost::shared_ptr<TBufferBase> ibuf,
|
||||
boost::shared_ptr<TBufferBase> obuf) {
|
||||
boost::shared_ptr<TProtocol> iprot(pfact_->getProtocol(ibuf));
|
||||
boost::shared_ptr<TProtocol> oprot(pfact_->getProtocol(obuf));
|
||||
return underlying_
|
||||
->process(apache::thrift::stdcxx::bind(&TAsyncProtocolProcessor::finish,
|
||||
_return,
|
||||
oprot,
|
||||
apache::thrift::stdcxx::placeholders::_1),
|
||||
iprot,
|
||||
oprot);
|
||||
}
|
||||
|
||||
/* static */ void TAsyncProtocolProcessor::finish(
|
||||
apache::thrift::stdcxx::function<void(bool healthy)> _return,
|
||||
boost::shared_ptr<TProtocol> oprot,
|
||||
bool healthy) {
|
||||
(void)oprot;
|
||||
// This is a stub function to hold a reference to oprot.
|
||||
return _return(healthy);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::async
|
55
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TAsyncProtocolProcessor.h
generated
vendored
Normal file
55
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TAsyncProtocolProcessor.h
generated
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_TNAME_ME_H_
|
||||
#define _THRIFT_TNAME_ME_H_ 1
|
||||
|
||||
#include <thrift/async/TAsyncProcessor.h>
|
||||
#include <thrift/async/TAsyncBufferProcessor.h>
|
||||
#include <thrift/protocol/TProtocol.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace async {
|
||||
|
||||
class TAsyncProtocolProcessor : public TAsyncBufferProcessor {
|
||||
public:
|
||||
TAsyncProtocolProcessor(boost::shared_ptr<TAsyncProcessor> underlying,
|
||||
boost::shared_ptr<apache::thrift::protocol::TProtocolFactory> pfact)
|
||||
: underlying_(underlying), pfact_(pfact) {}
|
||||
|
||||
virtual void process(apache::thrift::stdcxx::function<void(bool healthy)> _return,
|
||||
boost::shared_ptr<apache::thrift::transport::TBufferBase> ibuf,
|
||||
boost::shared_ptr<apache::thrift::transport::TBufferBase> obuf);
|
||||
|
||||
virtual ~TAsyncProtocolProcessor() {}
|
||||
|
||||
private:
|
||||
static void finish(apache::thrift::stdcxx::function<void(bool healthy)> _return,
|
||||
boost::shared_ptr<apache::thrift::protocol::TProtocol> oprot,
|
||||
bool healthy);
|
||||
|
||||
boost::shared_ptr<TAsyncProcessor> underlying_;
|
||||
boost::shared_ptr<apache::thrift::protocol::TProtocolFactory> pfact_;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::async
|
||||
|
||||
#endif // #ifndef _THRIFT_TNAME_ME_H_
|
242
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.cpp
generated
vendored
Normal file
242
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.cpp
generated
vendored
Normal file
|
@ -0,0 +1,242 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/async/TConcurrentClientSyncInfo.h>
|
||||
#include <thrift/TApplicationException.h>
|
||||
#include <thrift/transport/TTransportException.h>
|
||||
#include <limits>
|
||||
|
||||
namespace apache { namespace thrift { namespace async {
|
||||
|
||||
using namespace ::apache::thrift::concurrency;
|
||||
|
||||
TConcurrentClientSyncInfo::TConcurrentClientSyncInfo() :
|
||||
stop_(false),
|
||||
seqidMutex_(),
|
||||
// test rollover all the time
|
||||
nextseqid_((std::numeric_limits<int32_t>::max)()-10),
|
||||
seqidToMonitorMap_(),
|
||||
freeMonitors_(),
|
||||
writeMutex_(),
|
||||
readMutex_(),
|
||||
recvPending_(false),
|
||||
wakeupSomeone_(false),
|
||||
seqidPending_(0),
|
||||
fnamePending_(),
|
||||
mtypePending_(::apache::thrift::protocol::T_CALL)
|
||||
{
|
||||
freeMonitors_.reserve(MONITOR_CACHE_SIZE);
|
||||
}
|
||||
|
||||
bool TConcurrentClientSyncInfo::getPending(
|
||||
std::string &fname,
|
||||
::apache::thrift::protocol::TMessageType &mtype,
|
||||
int32_t &rseqid)
|
||||
{
|
||||
if(stop_)
|
||||
throwDeadConnection_();
|
||||
wakeupSomeone_ = false;
|
||||
if(recvPending_)
|
||||
{
|
||||
recvPending_ = false;
|
||||
rseqid = seqidPending_;
|
||||
fname = fnamePending_;
|
||||
mtype = mtypePending_;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TConcurrentClientSyncInfo::updatePending(
|
||||
const std::string &fname,
|
||||
::apache::thrift::protocol::TMessageType mtype,
|
||||
int32_t rseqid)
|
||||
{
|
||||
recvPending_ = true;
|
||||
seqidPending_ = rseqid;
|
||||
fnamePending_ = fname;
|
||||
mtypePending_ = mtype;
|
||||
MonitorPtr monitor;
|
||||
{
|
||||
Guard seqidGuard(seqidMutex_);
|
||||
MonitorMap::iterator i = seqidToMonitorMap_.find(rseqid);
|
||||
if(i == seqidToMonitorMap_.end())
|
||||
throwBadSeqId_();
|
||||
monitor = i->second;
|
||||
}
|
||||
monitor->notify();
|
||||
}
|
||||
|
||||
void TConcurrentClientSyncInfo::waitForWork(int32_t seqid)
|
||||
{
|
||||
MonitorPtr m;
|
||||
{
|
||||
Guard seqidGuard(seqidMutex_);
|
||||
m = seqidToMonitorMap_[seqid];
|
||||
}
|
||||
while(true)
|
||||
{
|
||||
// be very careful about setting state in this loop that affects waking up. You may exit
|
||||
// this function, attempt to grab some work, and someone else could have beaten you (or not
|
||||
// left) the read mutex, and that will put you right back in this loop, with the mangled
|
||||
// state you left behind.
|
||||
if(stop_)
|
||||
throwDeadConnection_();
|
||||
if(wakeupSomeone_)
|
||||
return;
|
||||
if(recvPending_ && seqidPending_ == seqid)
|
||||
return;
|
||||
m->waitForever();
|
||||
}
|
||||
}
|
||||
|
||||
void TConcurrentClientSyncInfo::throwBadSeqId_()
|
||||
{
|
||||
throw apache::thrift::TApplicationException(
|
||||
TApplicationException::BAD_SEQUENCE_ID,
|
||||
"server sent a bad seqid");
|
||||
}
|
||||
|
||||
void TConcurrentClientSyncInfo::throwDeadConnection_()
|
||||
{
|
||||
throw apache::thrift::transport::TTransportException(
|
||||
apache::thrift::transport::TTransportException::NOT_OPEN,
|
||||
"this client died on another thread, and is now in an unusable state");
|
||||
}
|
||||
|
||||
void TConcurrentClientSyncInfo::wakeupAnyone_(const Guard &)
|
||||
{
|
||||
wakeupSomeone_ = true;
|
||||
if(!seqidToMonitorMap_.empty())
|
||||
{
|
||||
// The monitor map maps integers to monitors. Larger integers are more recent
|
||||
// messages. Since this is ordered, it means that the last element is the most recent.
|
||||
// We are trying to guess which thread will have its message complete next, so we are picking
|
||||
// the most recent. The oldest message is likely to be some polling, long lived message.
|
||||
// If we guess right, the thread we wake up will handle the message that comes in.
|
||||
// If we guess wrong, the thread we wake up will hand off the work to the correct thread,
|
||||
// costing us an extra context switch.
|
||||
seqidToMonitorMap_.rbegin()->second->notify();
|
||||
}
|
||||
}
|
||||
|
||||
void TConcurrentClientSyncInfo::markBad_(const Guard &)
|
||||
{
|
||||
wakeupSomeone_ = true;
|
||||
stop_ = true;
|
||||
for(MonitorMap::iterator i = seqidToMonitorMap_.begin(); i != seqidToMonitorMap_.end(); ++i)
|
||||
i->second->notify();
|
||||
}
|
||||
|
||||
TConcurrentClientSyncInfo::MonitorPtr
|
||||
TConcurrentClientSyncInfo::newMonitor_(const Guard &)
|
||||
{
|
||||
if(freeMonitors_.empty())
|
||||
return MonitorPtr(new Monitor(&readMutex_));
|
||||
MonitorPtr retval;
|
||||
//swapping to avoid an atomic operation
|
||||
retval.swap(freeMonitors_.back());
|
||||
freeMonitors_.pop_back();
|
||||
return retval;
|
||||
}
|
||||
|
||||
void TConcurrentClientSyncInfo::deleteMonitor_(
|
||||
const Guard &,
|
||||
TConcurrentClientSyncInfo::MonitorPtr &m) /*noexcept*/
|
||||
{
|
||||
if(freeMonitors_.size() > MONITOR_CACHE_SIZE)
|
||||
{
|
||||
m.reset();
|
||||
return;
|
||||
}
|
||||
//freeMonitors_ was reserved up to MONITOR_CACHE_SIZE in the ctor,
|
||||
//so this shouldn't throw
|
||||
freeMonitors_.push_back(TConcurrentClientSyncInfo::MonitorPtr());
|
||||
//swapping to avoid an atomic operation
|
||||
m.swap(freeMonitors_.back());
|
||||
}
|
||||
|
||||
int32_t TConcurrentClientSyncInfo::generateSeqId()
|
||||
{
|
||||
Guard seqidGuard(seqidMutex_);
|
||||
if(stop_)
|
||||
throwDeadConnection_();
|
||||
|
||||
if(!seqidToMonitorMap_.empty())
|
||||
if(nextseqid_ == seqidToMonitorMap_.begin()->first)
|
||||
throw apache::thrift::TApplicationException(
|
||||
TApplicationException::BAD_SEQUENCE_ID,
|
||||
"about to repeat a seqid");
|
||||
int32_t newSeqId = nextseqid_++;
|
||||
seqidToMonitorMap_[newSeqId] = newMonitor_(seqidGuard);
|
||||
return newSeqId;
|
||||
}
|
||||
|
||||
TConcurrentRecvSentry::TConcurrentRecvSentry(TConcurrentClientSyncInfo *sync, int32_t seqid) :
|
||||
sync_(*sync),
|
||||
seqid_(seqid),
|
||||
committed_(false)
|
||||
{
|
||||
sync_.getReadMutex().lock();
|
||||
}
|
||||
|
||||
TConcurrentRecvSentry::~TConcurrentRecvSentry()
|
||||
{
|
||||
{
|
||||
Guard seqidGuard(sync_.seqidMutex_);
|
||||
sync_.deleteMonitor_(seqidGuard, sync_.seqidToMonitorMap_[seqid_]);
|
||||
|
||||
sync_.seqidToMonitorMap_.erase(seqid_);
|
||||
if(committed_)
|
||||
sync_.wakeupAnyone_(seqidGuard);
|
||||
else
|
||||
sync_.markBad_(seqidGuard);
|
||||
}
|
||||
sync_.getReadMutex().unlock();
|
||||
}
|
||||
|
||||
void TConcurrentRecvSentry::commit()
|
||||
{
|
||||
committed_ = true;
|
||||
}
|
||||
|
||||
TConcurrentSendSentry::TConcurrentSendSentry(TConcurrentClientSyncInfo *sync) :
|
||||
sync_(*sync),
|
||||
committed_(false)
|
||||
{
|
||||
sync_.getWriteMutex().lock();
|
||||
}
|
||||
|
||||
TConcurrentSendSentry::~TConcurrentSendSentry()
|
||||
{
|
||||
if(!committed_)
|
||||
{
|
||||
Guard seqidGuard(sync_.seqidMutex_);
|
||||
sync_.markBad_(seqidGuard);
|
||||
}
|
||||
sync_.getWriteMutex().unlock();
|
||||
}
|
||||
|
||||
void TConcurrentSendSentry::commit()
|
||||
{
|
||||
committed_ = true;
|
||||
}
|
||||
|
||||
|
||||
}}} // apache::thrift::async
|
126
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.h
generated
vendored
Normal file
126
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.h
generated
vendored
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
#ifndef _THRIFT_TCONCURRENTCLIENTSYNCINFO_H_
|
||||
#define _THRIFT_TCONCURRENTCLIENTSYNCINFO_H_ 1
|
||||
|
||||
#include <thrift/protocol/TProtocol.h>
|
||||
#include <thrift/concurrency/Mutex.h>
|
||||
#include <thrift/concurrency/Monitor.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace async {
|
||||
|
||||
class TConcurrentClientSyncInfo;
|
||||
|
||||
class TConcurrentSendSentry {
|
||||
public:
|
||||
explicit TConcurrentSendSentry(TConcurrentClientSyncInfo* sync);
|
||||
~TConcurrentSendSentry();
|
||||
|
||||
void commit();
|
||||
|
||||
private:
|
||||
TConcurrentClientSyncInfo& sync_;
|
||||
bool committed_;
|
||||
};
|
||||
|
||||
class TConcurrentRecvSentry {
|
||||
public:
|
||||
TConcurrentRecvSentry(TConcurrentClientSyncInfo* sync, int32_t seqid);
|
||||
~TConcurrentRecvSentry();
|
||||
|
||||
void commit();
|
||||
|
||||
private:
|
||||
TConcurrentClientSyncInfo& sync_;
|
||||
int32_t seqid_;
|
||||
bool committed_;
|
||||
};
|
||||
|
||||
class TConcurrentClientSyncInfo {
|
||||
private: // typedefs
|
||||
typedef boost::shared_ptr< ::apache::thrift::concurrency::Monitor> MonitorPtr;
|
||||
typedef std::map<int32_t, MonitorPtr> MonitorMap;
|
||||
|
||||
public:
|
||||
TConcurrentClientSyncInfo();
|
||||
|
||||
int32_t generateSeqId();
|
||||
|
||||
bool getPending(std::string& fname,
|
||||
::apache::thrift::protocol::TMessageType& mtype,
|
||||
int32_t& rseqid); /* requires readMutex_ */
|
||||
|
||||
void updatePending(const std::string& fname,
|
||||
::apache::thrift::protocol::TMessageType mtype,
|
||||
int32_t rseqid); /* requires readMutex_ */
|
||||
|
||||
void waitForWork(int32_t seqid); /* requires readMutex_ */
|
||||
|
||||
::apache::thrift::concurrency::Mutex& getReadMutex() { return readMutex_; }
|
||||
::apache::thrift::concurrency::Mutex& getWriteMutex() { return writeMutex_; }
|
||||
|
||||
private: // constants
|
||||
enum { MONITOR_CACHE_SIZE = 10 };
|
||||
|
||||
private: // functions
|
||||
MonitorPtr newMonitor_(
|
||||
const ::apache::thrift::concurrency::Guard& seqidGuard); /* requires seqidMutex_ */
|
||||
void deleteMonitor_(const ::apache::thrift::concurrency::Guard& seqidGuard, MonitorPtr& m);
|
||||
/*noexcept*/ /* requires seqidMutex_ */
|
||||
void wakeupAnyone_(
|
||||
const ::apache::thrift::concurrency::Guard& seqidGuard); /* requires seqidMutex_ */
|
||||
void markBad_(const ::apache::thrift::concurrency::Guard& seqidGuard); /* requires seqidMutex_ */
|
||||
void throwBadSeqId_();
|
||||
void throwDeadConnection_();
|
||||
|
||||
private: // data members
|
||||
volatile bool stop_;
|
||||
|
||||
::apache::thrift::concurrency::Mutex seqidMutex_;
|
||||
// begin seqidMutex_ protected members
|
||||
int32_t nextseqid_;
|
||||
MonitorMap seqidToMonitorMap_;
|
||||
std::vector<MonitorPtr> freeMonitors_;
|
||||
// end seqidMutex_ protected members
|
||||
|
||||
::apache::thrift::concurrency::Mutex writeMutex_;
|
||||
|
||||
::apache::thrift::concurrency::Mutex readMutex_;
|
||||
// begin readMutex_ protected members
|
||||
bool recvPending_;
|
||||
bool wakeupSomeone_;
|
||||
int32_t seqidPending_;
|
||||
std::string fnamePending_;
|
||||
::apache::thrift::protocol::TMessageType mtypePending_;
|
||||
// end readMutex_ protected members
|
||||
|
||||
friend class TConcurrentSendSentry;
|
||||
friend class TConcurrentRecvSentry;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::async
|
||||
|
||||
#endif // _THRIFT_TCONCURRENTCLIENTSYNCINFO_H_
|
155
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TEvhttpClientChannel.cpp
generated
vendored
Normal file
155
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TEvhttpClientChannel.cpp
generated
vendored
Normal file
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/async/TEvhttpClientChannel.h>
|
||||
#include <evhttp.h>
|
||||
#include <event2/buffer.h>
|
||||
#include <event2/buffer_compat.h>
|
||||
#include <thrift/transport/TBufferTransports.h>
|
||||
#include <thrift/protocol/TProtocolException.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
using namespace apache::thrift::protocol;
|
||||
using apache::thrift::transport::TTransportException;
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace async {
|
||||
|
||||
TEvhttpClientChannel::TEvhttpClientChannel(const std::string& host,
|
||||
const std::string& path,
|
||||
const char* address,
|
||||
int port,
|
||||
struct event_base* eb)
|
||||
: host_(host), path_(path), conn_(NULL) {
|
||||
conn_ = evhttp_connection_new(address, port);
|
||||
if (conn_ == NULL) {
|
||||
throw TException("evhttp_connection_new failed");
|
||||
}
|
||||
evhttp_connection_set_base(conn_, eb);
|
||||
}
|
||||
|
||||
TEvhttpClientChannel::~TEvhttpClientChannel() {
|
||||
if (conn_ != NULL) {
|
||||
evhttp_connection_free(conn_);
|
||||
}
|
||||
}
|
||||
|
||||
void TEvhttpClientChannel::sendAndRecvMessage(const VoidCallback& cob,
|
||||
apache::thrift::transport::TMemoryBuffer* sendBuf,
|
||||
apache::thrift::transport::TMemoryBuffer* recvBuf) {
|
||||
struct evhttp_request* req = evhttp_request_new(response, this);
|
||||
if (req == NULL) {
|
||||
throw TException("evhttp_request_new failed");
|
||||
}
|
||||
|
||||
int rv;
|
||||
|
||||
rv = evhttp_add_header(req->output_headers, "Host", host_.c_str());
|
||||
if (rv != 0) {
|
||||
throw TException("evhttp_add_header failed");
|
||||
}
|
||||
|
||||
rv = evhttp_add_header(req->output_headers, "Content-Type", "application/x-thrift");
|
||||
if (rv != 0) {
|
||||
throw TException("evhttp_add_header failed");
|
||||
}
|
||||
|
||||
uint8_t* obuf;
|
||||
uint32_t sz;
|
||||
sendBuf->getBuffer(&obuf, &sz);
|
||||
rv = evbuffer_add(req->output_buffer, obuf, sz);
|
||||
if (rv != 0) {
|
||||
throw TException("evbuffer_add failed");
|
||||
}
|
||||
|
||||
rv = evhttp_make_request(conn_, req, EVHTTP_REQ_POST, path_.c_str());
|
||||
if (rv != 0) {
|
||||
throw TException("evhttp_make_request failed");
|
||||
}
|
||||
|
||||
completionQueue_.push(Completion(cob, recvBuf));
|
||||
}
|
||||
|
||||
void TEvhttpClientChannel::sendMessage(const VoidCallback& cob,
|
||||
apache::thrift::transport::TMemoryBuffer* message) {
|
||||
(void)cob;
|
||||
(void)message;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"Unexpected call to TEvhttpClientChannel::sendMessage");
|
||||
}
|
||||
|
||||
void TEvhttpClientChannel::recvMessage(const VoidCallback& cob,
|
||||
apache::thrift::transport::TMemoryBuffer* message) {
|
||||
(void)cob;
|
||||
(void)message;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"Unexpected call to TEvhttpClientChannel::recvMessage");
|
||||
}
|
||||
|
||||
void TEvhttpClientChannel::finish(struct evhttp_request* req) {
|
||||
assert(!completionQueue_.empty());
|
||||
Completion completion = completionQueue_.front();
|
||||
completionQueue_.pop();
|
||||
if (req == NULL) {
|
||||
try {
|
||||
completion.first();
|
||||
} catch (const TTransportException& e) {
|
||||
if (e.getType() == TTransportException::END_OF_FILE)
|
||||
throw TException("connect failed");
|
||||
else
|
||||
throw;
|
||||
}
|
||||
return;
|
||||
} else if (req->response_code != 200) {
|
||||
try {
|
||||
completion.first();
|
||||
} catch (const TTransportException& e) {
|
||||
std::stringstream ss;
|
||||
ss << "server returned code " << req->response_code;
|
||||
if (req->response_code_line)
|
||||
ss << ": " << req->response_code_line;
|
||||
if (e.getType() == TTransportException::END_OF_FILE)
|
||||
throw TException(ss.str());
|
||||
else
|
||||
throw;
|
||||
}
|
||||
return;
|
||||
}
|
||||
completion.second->resetBuffer(EVBUFFER_DATA(req->input_buffer),
|
||||
static_cast<uint32_t>(EVBUFFER_LENGTH(req->input_buffer)));
|
||||
completion.first();
|
||||
return;
|
||||
}
|
||||
|
||||
/* static */ void TEvhttpClientChannel::response(struct evhttp_request* req, void* arg) {
|
||||
TEvhttpClientChannel* self = (TEvhttpClientChannel*)arg;
|
||||
try {
|
||||
self->finish(req);
|
||||
} catch (std::exception& e) {
|
||||
// don't propagate a C++ exception in C code (e.g. libevent)
|
||||
std::cerr << "TEvhttpClientChannel::response exception thrown (ignored): " << e.what()
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::async
|
86
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TEvhttpClientChannel.h
generated
vendored
Normal file
86
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TEvhttpClientChannel.h
generated
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_TEVHTTP_CLIENT_CHANNEL_H_
|
||||
#define _THRIFT_TEVHTTP_CLIENT_CHANNEL_H_ 1
|
||||
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <thrift/async/TAsyncChannel.h>
|
||||
|
||||
struct event_base;
|
||||
struct evhttp_connection;
|
||||
struct evhttp_request;
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace transport {
|
||||
class TMemoryBuffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace async {
|
||||
|
||||
class TEvhttpClientChannel : public TAsyncChannel {
|
||||
public:
|
||||
using TAsyncChannel::VoidCallback;
|
||||
|
||||
TEvhttpClientChannel(const std::string& host,
|
||||
const std::string& path,
|
||||
const char* address,
|
||||
int port,
|
||||
struct event_base* eb);
|
||||
~TEvhttpClientChannel();
|
||||
|
||||
virtual void sendAndRecvMessage(const VoidCallback& cob,
|
||||
apache::thrift::transport::TMemoryBuffer* sendBuf,
|
||||
apache::thrift::transport::TMemoryBuffer* recvBuf);
|
||||
|
||||
virtual void sendMessage(const VoidCallback& cob,
|
||||
apache::thrift::transport::TMemoryBuffer* message);
|
||||
virtual void recvMessage(const VoidCallback& cob,
|
||||
apache::thrift::transport::TMemoryBuffer* message);
|
||||
|
||||
void finish(struct evhttp_request* req);
|
||||
|
||||
// XXX
|
||||
virtual bool good() const { return true; }
|
||||
virtual bool error() const { return false; }
|
||||
virtual bool timedOut() const { return false; }
|
||||
|
||||
private:
|
||||
static void response(struct evhttp_request* req, void* arg);
|
||||
|
||||
std::string host_;
|
||||
std::string path_;
|
||||
typedef std::pair<VoidCallback, apache::thrift::transport::TMemoryBuffer*> Completion;
|
||||
typedef std::queue<Completion> CompletionQueue;
|
||||
CompletionQueue completionQueue_;
|
||||
struct evhttp_connection* conn_;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::async
|
||||
|
||||
#endif // #ifndef _THRIFT_TEVHTTP_CLIENT_CHANNEL_H_
|
159
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TEvhttpServer.cpp
generated
vendored
Normal file
159
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TEvhttpServer.cpp
generated
vendored
Normal file
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/async/TEvhttpServer.h>
|
||||
#include <thrift/async/TAsyncBufferProcessor.h>
|
||||
#include <thrift/transport/TBufferTransports.h>
|
||||
#include <evhttp.h>
|
||||
#include <event2/buffer.h>
|
||||
#include <event2/buffer_compat.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#ifndef HTTP_INTERNAL // libevent < 2
|
||||
#define HTTP_INTERNAL 500
|
||||
#endif
|
||||
|
||||
using apache::thrift::transport::TMemoryBuffer;
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace async {
|
||||
|
||||
struct TEvhttpServer::RequestContext {
|
||||
struct evhttp_request* req;
|
||||
boost::shared_ptr<apache::thrift::transport::TMemoryBuffer> ibuf;
|
||||
boost::shared_ptr<apache::thrift::transport::TMemoryBuffer> obuf;
|
||||
|
||||
RequestContext(struct evhttp_request* req);
|
||||
};
|
||||
|
||||
TEvhttpServer::TEvhttpServer(boost::shared_ptr<TAsyncBufferProcessor> processor)
|
||||
: processor_(processor), eb_(NULL), eh_(NULL) {
|
||||
}
|
||||
|
||||
TEvhttpServer::TEvhttpServer(boost::shared_ptr<TAsyncBufferProcessor> processor, int port)
|
||||
: processor_(processor), eb_(NULL), eh_(NULL) {
|
||||
// Create event_base and evhttp.
|
||||
eb_ = event_base_new();
|
||||
if (eb_ == NULL) {
|
||||
throw TException("event_base_new failed");
|
||||
}
|
||||
eh_ = evhttp_new(eb_);
|
||||
if (eh_ == NULL) {
|
||||
event_base_free(eb_);
|
||||
throw TException("evhttp_new failed");
|
||||
}
|
||||
|
||||
// Bind to port.
|
||||
int ret = evhttp_bind_socket(eh_, NULL, port);
|
||||
if (ret < 0) {
|
||||
evhttp_free(eh_);
|
||||
event_base_free(eb_);
|
||||
throw TException("evhttp_bind_socket failed");
|
||||
}
|
||||
|
||||
// Register a handler. If you use the other constructor,
|
||||
// you will want to do this yourself.
|
||||
// Don't forget to unregister before destorying this TEvhttpServer.
|
||||
evhttp_set_cb(eh_, "/", request, (void*)this);
|
||||
}
|
||||
|
||||
TEvhttpServer::~TEvhttpServer() {
|
||||
if (eh_ != NULL) {
|
||||
evhttp_free(eh_);
|
||||
}
|
||||
if (eb_ != NULL) {
|
||||
event_base_free(eb_);
|
||||
}
|
||||
}
|
||||
|
||||
int TEvhttpServer::serve() {
|
||||
if (eb_ == NULL) {
|
||||
throw TException("Unexpected call to TEvhttpServer::serve");
|
||||
}
|
||||
return event_base_dispatch(eb_);
|
||||
}
|
||||
|
||||
TEvhttpServer::RequestContext::RequestContext(struct evhttp_request* req)
|
||||
: req(req),
|
||||
ibuf(new TMemoryBuffer(EVBUFFER_DATA(req->input_buffer),
|
||||
static_cast<uint32_t>(EVBUFFER_LENGTH(req->input_buffer)))),
|
||||
obuf(new TMemoryBuffer()) {
|
||||
}
|
||||
|
||||
void TEvhttpServer::request(struct evhttp_request* req, void* self) {
|
||||
try {
|
||||
static_cast<TEvhttpServer*>(self)->process(req);
|
||||
} catch (std::exception& e) {
|
||||
evhttp_send_reply(req, HTTP_INTERNAL, e.what(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void TEvhttpServer::process(struct evhttp_request* req) {
|
||||
RequestContext* ctx = new RequestContext(req);
|
||||
return processor_->process(apache::thrift::stdcxx::bind(&TEvhttpServer::complete,
|
||||
this,
|
||||
ctx,
|
||||
apache::thrift::stdcxx::placeholders::_1),
|
||||
ctx->ibuf,
|
||||
ctx->obuf);
|
||||
}
|
||||
|
||||
void TEvhttpServer::complete(RequestContext* ctx, bool success) {
|
||||
(void)success;
|
||||
std::auto_ptr<RequestContext> ptr(ctx);
|
||||
|
||||
int code = success ? 200 : 400;
|
||||
const char* reason = success ? "OK" : "Bad Request";
|
||||
|
||||
int rv = evhttp_add_header(ctx->req->output_headers, "Content-Type", "application/x-thrift");
|
||||
if (rv != 0) {
|
||||
// TODO: Log an error.
|
||||
std::cerr << "evhttp_add_header failed " << __FILE__ << ":" << __LINE__ << std::endl;
|
||||
}
|
||||
|
||||
struct evbuffer* buf = evbuffer_new();
|
||||
if (buf == NULL) {
|
||||
// TODO: Log an error.
|
||||
std::cerr << "evbuffer_new failed " << __FILE__ << ":" << __LINE__ << std::endl;
|
||||
} else {
|
||||
uint8_t* obuf;
|
||||
uint32_t sz;
|
||||
ctx->obuf->getBuffer(&obuf, &sz);
|
||||
int ret = evbuffer_add(buf, obuf, sz);
|
||||
if (ret != 0) {
|
||||
// TODO: Log an error.
|
||||
std::cerr << "evhttp_add failed with " << ret << " " << __FILE__ << ":" << __LINE__
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
evhttp_send_reply(ctx->req, code, reason, buf);
|
||||
if (buf != NULL) {
|
||||
evbuffer_free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
struct event_base* TEvhttpServer::getEventBase() {
|
||||
return eb_;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::async
|
74
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TEvhttpServer.h
generated
vendored
Normal file
74
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/async/TEvhttpServer.h
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_TEVHTTP_SERVER_H_
|
||||
#define _THRIFT_TEVHTTP_SERVER_H_ 1
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
struct event_base;
|
||||
struct evhttp;
|
||||
struct evhttp_request;
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace async {
|
||||
|
||||
class TAsyncBufferProcessor;
|
||||
|
||||
class TEvhttpServer {
|
||||
public:
|
||||
/**
|
||||
* Create a TEvhttpServer for use with an external evhttp instance.
|
||||
* Must be manually installed with evhttp_set_cb, using
|
||||
* TEvhttpServer::request as the callback and the
|
||||
* address of the server as the extra arg.
|
||||
* Do not call "serve" on this server.
|
||||
*/
|
||||
TEvhttpServer(boost::shared_ptr<TAsyncBufferProcessor> processor);
|
||||
|
||||
/**
|
||||
* Create a TEvhttpServer with an embedded event_base and evhttp,
|
||||
* listening on port and responding on the endpoint "/".
|
||||
* Call "serve" on this server to serve forever.
|
||||
*/
|
||||
TEvhttpServer(boost::shared_ptr<TAsyncBufferProcessor> processor, int port);
|
||||
|
||||
~TEvhttpServer();
|
||||
|
||||
static void request(struct evhttp_request* req, void* self);
|
||||
int serve();
|
||||
|
||||
struct event_base* getEventBase();
|
||||
|
||||
private:
|
||||
struct RequestContext;
|
||||
|
||||
void process(struct evhttp_request* req);
|
||||
void complete(RequestContext* ctx, bool success);
|
||||
|
||||
boost::shared_ptr<TAsyncBufferProcessor> processor_;
|
||||
struct event_base* eb_;
|
||||
struct evhttp* eh_;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::async
|
||||
|
||||
#endif // #ifndef _THRIFT_TEVHTTP_SERVER_H_
|
214
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/BoostMonitor.cpp
generated
vendored
Normal file
214
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/BoostMonitor.cpp
generated
vendored
Normal file
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/thrift-config.h>
|
||||
|
||||
#include <thrift/concurrency/Monitor.h>
|
||||
#include <thrift/concurrency/Exception.h>
|
||||
#include <thrift/concurrency/Util.h>
|
||||
#include <thrift/transport/PlatformSocket.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
/**
|
||||
* Monitor implementation using the boost thread library
|
||||
*
|
||||
* @version $Id:$
|
||||
*/
|
||||
class Monitor::Impl : public boost::condition_variable_any {
|
||||
|
||||
public:
|
||||
Impl() : ownedMutex_(new Mutex()), mutex_(NULL) { init(ownedMutex_.get()); }
|
||||
|
||||
Impl(Mutex* mutex) : mutex_(NULL) { init(mutex); }
|
||||
|
||||
Impl(Monitor* monitor) : mutex_(NULL) { init(&(monitor->mutex())); }
|
||||
|
||||
Mutex& mutex() { return *mutex_; }
|
||||
void lock() { mutex().lock(); }
|
||||
void unlock() { mutex().unlock(); }
|
||||
|
||||
/**
|
||||
* Exception-throwing version of waitForTimeRelative(), called simply
|
||||
* wait(int64) for historical reasons. Timeout is in milliseconds.
|
||||
*
|
||||
* If the condition occurs, this function returns cleanly; on timeout or
|
||||
* error an exception is thrown.
|
||||
*/
|
||||
void wait(int64_t timeout_ms) {
|
||||
int result = waitForTimeRelative(timeout_ms);
|
||||
if (result == THRIFT_ETIMEDOUT) {
|
||||
throw TimedOutException();
|
||||
} else if (result != 0) {
|
||||
throw TException("Monitor::wait() failed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits until the specified timeout in milliseconds for the condition to
|
||||
* occur, or waits forever if timeout_ms == 0.
|
||||
*
|
||||
* Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
|
||||
*/
|
||||
int waitForTimeRelative(int64_t timeout_ms) {
|
||||
if (timeout_ms == 0LL) {
|
||||
return waitForever();
|
||||
}
|
||||
|
||||
assert(mutex_);
|
||||
boost::timed_mutex* mutexImpl
|
||||
= reinterpret_cast<boost::timed_mutex*>(mutex_->getUnderlyingImpl());
|
||||
assert(mutexImpl);
|
||||
|
||||
boost::timed_mutex::scoped_lock lock(*mutexImpl, boost::adopt_lock);
|
||||
int res
|
||||
= timed_wait(lock, boost::get_system_time() + boost::posix_time::milliseconds(timeout_ms))
|
||||
? 0
|
||||
: THRIFT_ETIMEDOUT;
|
||||
lock.release();
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits until the absolute time specified using struct THRIFT_TIMESPEC.
|
||||
* Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
|
||||
*/
|
||||
int waitForTime(const THRIFT_TIMESPEC* abstime) {
|
||||
struct timeval temp;
|
||||
temp.tv_sec = static_cast<long>(abstime->tv_sec);
|
||||
temp.tv_usec = static_cast<long>(abstime->tv_nsec) / 1000;
|
||||
return waitForTime(&temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits until the absolute time specified using struct timeval.
|
||||
* Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
|
||||
*/
|
||||
int waitForTime(const struct timeval* abstime) {
|
||||
assert(mutex_);
|
||||
boost::timed_mutex* mutexImpl = static_cast<boost::timed_mutex*>(mutex_->getUnderlyingImpl());
|
||||
assert(mutexImpl);
|
||||
|
||||
struct timeval currenttime;
|
||||
Util::toTimeval(currenttime, Util::currentTime());
|
||||
|
||||
long tv_sec = static_cast<long>(abstime->tv_sec - currenttime.tv_sec);
|
||||
long tv_usec = static_cast<long>(abstime->tv_usec - currenttime.tv_usec);
|
||||
if (tv_sec < 0)
|
||||
tv_sec = 0;
|
||||
if (tv_usec < 0)
|
||||
tv_usec = 0;
|
||||
|
||||
boost::timed_mutex::scoped_lock lock(*mutexImpl, boost::adopt_lock);
|
||||
int res = timed_wait(lock,
|
||||
boost::get_system_time() + boost::posix_time::seconds(tv_sec)
|
||||
+ boost::posix_time::microseconds(tv_usec))
|
||||
? 0
|
||||
: THRIFT_ETIMEDOUT;
|
||||
lock.release();
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits forever until the condition occurs.
|
||||
* Returns 0 if condition occurs, or an error code otherwise.
|
||||
*/
|
||||
int waitForever() {
|
||||
assert(mutex_);
|
||||
boost::timed_mutex* mutexImpl
|
||||
= reinterpret_cast<boost::timed_mutex*>(mutex_->getUnderlyingImpl());
|
||||
assert(mutexImpl);
|
||||
|
||||
boost::timed_mutex::scoped_lock lock(*mutexImpl, boost::adopt_lock);
|
||||
((boost::condition_variable_any*)this)->wait(lock);
|
||||
lock.release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void notify() { notify_one(); }
|
||||
|
||||
void notifyAll() { notify_all(); }
|
||||
|
||||
private:
|
||||
void init(Mutex* mutex) { mutex_ = mutex; }
|
||||
|
||||
boost::scoped_ptr<Mutex> ownedMutex_;
|
||||
Mutex* mutex_;
|
||||
};
|
||||
|
||||
Monitor::Monitor() : impl_(new Monitor::Impl()) {
|
||||
}
|
||||
Monitor::Monitor(Mutex* mutex) : impl_(new Monitor::Impl(mutex)) {
|
||||
}
|
||||
Monitor::Monitor(Monitor* monitor) : impl_(new Monitor::Impl(monitor)) {
|
||||
}
|
||||
|
||||
Monitor::~Monitor() {
|
||||
delete impl_;
|
||||
}
|
||||
|
||||
Mutex& Monitor::mutex() const {
|
||||
return const_cast<Monitor::Impl*>(impl_)->mutex();
|
||||
}
|
||||
|
||||
void Monitor::lock() const {
|
||||
const_cast<Monitor::Impl*>(impl_)->lock();
|
||||
}
|
||||
|
||||
void Monitor::unlock() const {
|
||||
const_cast<Monitor::Impl*>(impl_)->unlock();
|
||||
}
|
||||
|
||||
void Monitor::wait(int64_t timeout) const {
|
||||
const_cast<Monitor::Impl*>(impl_)->wait(timeout);
|
||||
}
|
||||
|
||||
int Monitor::waitForTime(const THRIFT_TIMESPEC* abstime) const {
|
||||
return const_cast<Monitor::Impl*>(impl_)->waitForTime(abstime);
|
||||
}
|
||||
|
||||
int Monitor::waitForTime(const timeval* abstime) const {
|
||||
return const_cast<Monitor::Impl*>(impl_)->waitForTime(abstime);
|
||||
}
|
||||
|
||||
int Monitor::waitForTimeRelative(int64_t timeout_ms) const {
|
||||
return const_cast<Monitor::Impl*>(impl_)->waitForTimeRelative(timeout_ms);
|
||||
}
|
||||
|
||||
int Monitor::waitForever() const {
|
||||
return const_cast<Monitor::Impl*>(impl_)->waitForever();
|
||||
}
|
||||
|
||||
void Monitor::notify() const {
|
||||
const_cast<Monitor::Impl*>(impl_)->notify();
|
||||
}
|
||||
|
||||
void Monitor::notifyAll() const {
|
||||
const_cast<Monitor::Impl*>(impl_)->notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
71
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/BoostMutex.cpp
generated
vendored
Normal file
71
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/BoostMutex.cpp
generated
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/thrift-config.h>
|
||||
|
||||
#include <thrift/concurrency/Mutex.h>
|
||||
#include <thrift/concurrency/Util.h>
|
||||
#include <thrift/Thrift.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
/**
|
||||
* Implementation of Mutex class using boost interprocess mutex
|
||||
*
|
||||
* @version $Id:$
|
||||
*/
|
||||
class Mutex::impl : public boost::timed_mutex {};
|
||||
|
||||
Mutex::Mutex(Initializer init) : impl_(new Mutex::impl()) {
|
||||
THRIFT_UNUSED_VARIABLE(init);
|
||||
}
|
||||
|
||||
void* Mutex::getUnderlyingImpl() const {
|
||||
return impl_.get();
|
||||
}
|
||||
|
||||
void Mutex::lock() const {
|
||||
impl_->lock();
|
||||
}
|
||||
|
||||
bool Mutex::trylock() const {
|
||||
return impl_->try_lock();
|
||||
}
|
||||
|
||||
bool Mutex::timedlock(int64_t ms) const {
|
||||
return impl_->timed_lock(boost::get_system_time() + boost::posix_time::milliseconds(ms));
|
||||
}
|
||||
|
||||
void Mutex::unlock() const {
|
||||
impl_->unlock();
|
||||
}
|
||||
|
||||
void Mutex::DEFAULT_INITIALIZER(void* arg) {
|
||||
THRIFT_UNUSED_VARIABLE(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
147
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/BoostThreadFactory.cpp
generated
vendored
Normal file
147
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/BoostThreadFactory.cpp
generated
vendored
Normal file
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/thrift-config.h>
|
||||
|
||||
#if USE_BOOST_THREAD
|
||||
|
||||
#include <thrift/concurrency/BoostThreadFactory.h>
|
||||
#include <thrift/concurrency/Exception.h>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
using boost::shared_ptr;
|
||||
using boost::weak_ptr;
|
||||
|
||||
/**
|
||||
* The boost thread class.
|
||||
*
|
||||
* @version $Id:$
|
||||
*/
|
||||
class BoostThread : public Thread {
|
||||
public:
|
||||
enum STATE { uninitialized, starting, started, stopping, stopped };
|
||||
|
||||
static void* threadMain(void* arg);
|
||||
|
||||
private:
|
||||
std::auto_ptr<boost::thread> thread_;
|
||||
STATE state_;
|
||||
weak_ptr<BoostThread> self_;
|
||||
bool detached_;
|
||||
|
||||
public:
|
||||
BoostThread(bool detached, shared_ptr<Runnable> runnable)
|
||||
: state_(uninitialized), detached_(detached) {
|
||||
this->Thread::runnable(runnable);
|
||||
}
|
||||
|
||||
~BoostThread() {
|
||||
if (!detached_) {
|
||||
try {
|
||||
join();
|
||||
} catch (...) {
|
||||
// We're really hosed.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void start() {
|
||||
if (state_ != uninitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create reference
|
||||
shared_ptr<BoostThread>* selfRef = new shared_ptr<BoostThread>();
|
||||
*selfRef = self_.lock();
|
||||
|
||||
state_ = starting;
|
||||
|
||||
thread_
|
||||
= std::auto_ptr<boost::thread>(new boost::thread(boost::bind(threadMain, (void*)selfRef)));
|
||||
|
||||
if (detached_)
|
||||
thread_->detach();
|
||||
}
|
||||
|
||||
void join() {
|
||||
if (!detached_ && state_ != uninitialized) {
|
||||
thread_->join();
|
||||
}
|
||||
}
|
||||
|
||||
Thread::id_t getId() { return thread_.get() ? thread_->get_id() : boost::thread::id(); }
|
||||
|
||||
shared_ptr<Runnable> runnable() const { return Thread::runnable(); }
|
||||
|
||||
void runnable(shared_ptr<Runnable> value) { Thread::runnable(value); }
|
||||
|
||||
void weakRef(shared_ptr<BoostThread> self) {
|
||||
assert(self.get() == this);
|
||||
self_ = weak_ptr<BoostThread>(self);
|
||||
}
|
||||
};
|
||||
|
||||
void* BoostThread::threadMain(void* arg) {
|
||||
shared_ptr<BoostThread> thread = *(shared_ptr<BoostThread>*)arg;
|
||||
delete reinterpret_cast<shared_ptr<BoostThread>*>(arg);
|
||||
|
||||
if (!thread) {
|
||||
return (void*)0;
|
||||
}
|
||||
|
||||
if (thread->state_ != starting) {
|
||||
return (void*)0;
|
||||
}
|
||||
|
||||
thread->state_ = started;
|
||||
thread->runnable()->run();
|
||||
|
||||
if (thread->state_ != stopping && thread->state_ != stopped) {
|
||||
thread->state_ = stopping;
|
||||
}
|
||||
return (void*)0;
|
||||
}
|
||||
|
||||
BoostThreadFactory::BoostThreadFactory(bool detached)
|
||||
: ThreadFactory(detached) {
|
||||
}
|
||||
|
||||
shared_ptr<Thread> BoostThreadFactory::newThread(shared_ptr<Runnable> runnable) const {
|
||||
shared_ptr<BoostThread> result = shared_ptr<BoostThread>(new BoostThread(isDetached(), runnable));
|
||||
result->weakRef(result);
|
||||
runnable->thread(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
Thread::id_t BoostThreadFactory::getCurrentThreadId() const {
|
||||
return boost::this_thread::get_id();
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
||||
|
||||
#endif // USE_BOOST_THREAD
|
64
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/BoostThreadFactory.h
generated
vendored
Normal file
64
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/BoostThreadFactory.h
generated
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_CONCURRENCY_BOOSTTHREADFACTORY_H_
|
||||
#define _THRIFT_CONCURRENCY_BOOSTTHREADFACTORY_H_ 1
|
||||
|
||||
#include <thrift/concurrency/Thread.h>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
/**
|
||||
* A thread factory to create posix threads
|
||||
*
|
||||
* @version $Id:$
|
||||
*/
|
||||
class BoostThreadFactory : public ThreadFactory {
|
||||
|
||||
public:
|
||||
/**
|
||||
* Boost thread factory. All threads created by a factory are reference-counted
|
||||
* via boost::shared_ptr and boost::weak_ptr. The factory guarantees that threads and
|
||||
* the Runnable tasks they host will be properly cleaned up once the last strong reference
|
||||
* to both is given up.
|
||||
*
|
||||
* Threads are created with the specified boost policy, priority, stack-size. A detachable thread
|
||||
* is not joinable.
|
||||
*
|
||||
* By default threads are not joinable.
|
||||
*/
|
||||
|
||||
BoostThreadFactory(bool detached = true);
|
||||
|
||||
// From ThreadFactory;
|
||||
boost::shared_ptr<Thread> newThread(boost::shared_ptr<Runnable> runnable) const;
|
||||
|
||||
// From ThreadFactory;
|
||||
Thread::id_t getCurrentThreadId() const;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
||||
|
||||
#endif // #ifndef _THRIFT_CONCURRENCY_BOOSTTHREADFACTORY_H_
|
64
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/Exception.h
generated
vendored
Normal file
64
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/Exception.h
generated
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_CONCURRENCY_EXCEPTION_H_
|
||||
#define _THRIFT_CONCURRENCY_EXCEPTION_H_ 1
|
||||
|
||||
#include <exception>
|
||||
#include <thrift/Thrift.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
class NoSuchTaskException : public apache::thrift::TException {};
|
||||
|
||||
class UncancellableTaskException : public apache::thrift::TException {};
|
||||
|
||||
class InvalidArgumentException : public apache::thrift::TException {};
|
||||
|
||||
class IllegalStateException : public apache::thrift::TException {
|
||||
public:
|
||||
IllegalStateException() {}
|
||||
IllegalStateException(const std::string& message) : TException(message) {}
|
||||
};
|
||||
|
||||
class TimedOutException : public apache::thrift::TException {
|
||||
public:
|
||||
TimedOutException() : TException("TimedOutException"){};
|
||||
TimedOutException(const std::string& message) : TException(message) {}
|
||||
};
|
||||
|
||||
class TooManyPendingTasksException : public apache::thrift::TException {
|
||||
public:
|
||||
TooManyPendingTasksException() : TException("TooManyPendingTasksException"){};
|
||||
TooManyPendingTasksException(const std::string& message) : TException(message) {}
|
||||
};
|
||||
|
||||
class SystemResourceException : public apache::thrift::TException {
|
||||
public:
|
||||
SystemResourceException() {}
|
||||
|
||||
SystemResourceException(const std::string& message) : TException(message) {}
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
||||
|
||||
#endif // #ifndef _THRIFT_CONCURRENCY_EXCEPTION_H_
|
118
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/FunctionRunner.h
generated
vendored
Normal file
118
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/FunctionRunner.h
generated
vendored
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_CONCURRENCY_FUNCTION_RUNNER_H
|
||||
#define _THRIFT_CONCURRENCY_FUNCTION_RUNNER_H 1
|
||||
|
||||
#include <thrift/cxxfunctional.h>
|
||||
#include <thrift/concurrency/Thread.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
/**
|
||||
* Convenient implementation of Runnable that will execute arbitrary callbacks.
|
||||
* Interfaces are provided to accept both a generic 'void(void)' callback, and
|
||||
* a 'void* (void*)' pthread_create-style callback.
|
||||
*
|
||||
* Example use:
|
||||
* void* my_thread_main(void* arg);
|
||||
* shared_ptr<ThreadFactory> factory = ...;
|
||||
* // To create a thread that executes my_thread_main once:
|
||||
* shared_ptr<Thread> thread = factory->newThread(
|
||||
* FunctionRunner::create(my_thread_main, some_argument));
|
||||
* thread->start();
|
||||
*
|
||||
* bool A::foo();
|
||||
* A* a = new A();
|
||||
* // To create a thread that executes a.foo() every 100 milliseconds:
|
||||
* factory->newThread(FunctionRunner::create(
|
||||
* apache::thrift::stdcxx::bind(&A::foo, a), 100))->start();
|
||||
*
|
||||
*/
|
||||
|
||||
class FunctionRunner : public Runnable {
|
||||
public:
|
||||
// This is the type of callback 'pthread_create()' expects.
|
||||
typedef void* (*PthreadFuncPtr)(void* arg);
|
||||
// This a fully-generic void(void) callback for custom bindings.
|
||||
typedef apache::thrift::stdcxx::function<void()> VoidFunc;
|
||||
|
||||
typedef apache::thrift::stdcxx::function<bool()> BoolFunc;
|
||||
|
||||
/**
|
||||
* Syntactic sugar to make it easier to create new FunctionRunner
|
||||
* objects wrapped in shared_ptr.
|
||||
*/
|
||||
static boost::shared_ptr<FunctionRunner> create(const VoidFunc& cob) {
|
||||
return boost::shared_ptr<FunctionRunner>(new FunctionRunner(cob));
|
||||
}
|
||||
|
||||
static boost::shared_ptr<FunctionRunner> create(PthreadFuncPtr func, void* arg) {
|
||||
return boost::shared_ptr<FunctionRunner>(new FunctionRunner(func, arg));
|
||||
}
|
||||
|
||||
private:
|
||||
static void pthread_func_wrapper(PthreadFuncPtr func, void* arg) {
|
||||
// discard return value
|
||||
func(arg);
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* Given a 'pthread_create' style callback, this FunctionRunner will
|
||||
* execute the given callback. Note that the 'void*' return value is ignored.
|
||||
*/
|
||||
FunctionRunner(PthreadFuncPtr func, void* arg)
|
||||
: func_(apache::thrift::stdcxx::bind(pthread_func_wrapper, func, arg)), intervalMs_(-1) {}
|
||||
|
||||
/**
|
||||
* Given a generic callback, this FunctionRunner will execute it.
|
||||
*/
|
||||
FunctionRunner(const VoidFunc& cob) : func_(cob), intervalMs_(-1) {}
|
||||
|
||||
/**
|
||||
* Given a bool foo(...) type callback, FunctionRunner will execute
|
||||
* the callback repeatedly with 'intervalMs' milliseconds between the calls,
|
||||
* until it returns false. Note that the actual interval between calls will
|
||||
* be intervalMs plus execution time of the callback.
|
||||
*/
|
||||
FunctionRunner(const BoolFunc& cob, int intervalMs) : repFunc_(cob), intervalMs_(intervalMs) {}
|
||||
|
||||
void run() {
|
||||
if (repFunc_) {
|
||||
while (repFunc_()) {
|
||||
THRIFT_SLEEP_USEC(intervalMs_ * 1000);
|
||||
}
|
||||
} else {
|
||||
func_();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
VoidFunc func_;
|
||||
BoolFunc repFunc_;
|
||||
int intervalMs_;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
||||
|
||||
#endif // #ifndef _THRIFT_CONCURRENCY_FUNCTION_RUNNER_H
|
224
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/Monitor.cpp
generated
vendored
Normal file
224
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/Monitor.cpp
generated
vendored
Normal file
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/thrift-config.h>
|
||||
|
||||
#include <thrift/concurrency/Monitor.h>
|
||||
#include <thrift/concurrency/Exception.h>
|
||||
#include <thrift/concurrency/Util.h>
|
||||
#include <thrift/transport/PlatformSocket.h>
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
using boost::scoped_ptr;
|
||||
|
||||
/**
|
||||
* Monitor implementation using the POSIX pthread library
|
||||
*
|
||||
* @version $Id:$
|
||||
*/
|
||||
class Monitor::Impl {
|
||||
|
||||
public:
|
||||
Impl() : ownedMutex_(new Mutex()), mutex_(NULL), condInitialized_(false) {
|
||||
init(ownedMutex_.get());
|
||||
}
|
||||
|
||||
Impl(Mutex* mutex) : mutex_(NULL), condInitialized_(false) { init(mutex); }
|
||||
|
||||
Impl(Monitor* monitor) : mutex_(NULL), condInitialized_(false) { init(&(monitor->mutex())); }
|
||||
|
||||
~Impl() { cleanup(); }
|
||||
|
||||
Mutex& mutex() { return *mutex_; }
|
||||
void lock() { mutex().lock(); }
|
||||
void unlock() { mutex().unlock(); }
|
||||
|
||||
/**
|
||||
* Exception-throwing version of waitForTimeRelative(), called simply
|
||||
* wait(int64) for historical reasons. Timeout is in milliseconds.
|
||||
*
|
||||
* If the condition occurs, this function returns cleanly; on timeout or
|
||||
* error an exception is thrown.
|
||||
*/
|
||||
void wait(int64_t timeout_ms) const {
|
||||
int result = waitForTimeRelative(timeout_ms);
|
||||
if (result == THRIFT_ETIMEDOUT) {
|
||||
// pthread_cond_timedwait has been observed to return early on
|
||||
// various platforms, so comment out this assert.
|
||||
// assert(Util::currentTime() >= (now + timeout));
|
||||
throw TimedOutException();
|
||||
} else if (result != 0) {
|
||||
throw TException("pthread_cond_wait() or pthread_cond_timedwait() failed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits until the specified timeout in milliseconds for the condition to
|
||||
* occur, or waits forever if timeout_ms == 0.
|
||||
*
|
||||
* Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
|
||||
*/
|
||||
int waitForTimeRelative(int64_t timeout_ms) const {
|
||||
if (timeout_ms == 0LL) {
|
||||
return waitForever();
|
||||
}
|
||||
|
||||
struct THRIFT_TIMESPEC abstime;
|
||||
Util::toTimespec(abstime, Util::currentTime() + timeout_ms);
|
||||
return waitForTime(&abstime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits until the absolute time specified using struct THRIFT_TIMESPEC.
|
||||
* Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
|
||||
*/
|
||||
int waitForTime(const THRIFT_TIMESPEC* abstime) const {
|
||||
assert(mutex_);
|
||||
pthread_mutex_t* mutexImpl = reinterpret_cast<pthread_mutex_t*>(mutex_->getUnderlyingImpl());
|
||||
assert(mutexImpl);
|
||||
|
||||
// XXX Need to assert that caller owns mutex
|
||||
return pthread_cond_timedwait(&pthread_cond_, mutexImpl, abstime);
|
||||
}
|
||||
|
||||
int waitForTime(const struct timeval* abstime) const {
|
||||
struct THRIFT_TIMESPEC temp;
|
||||
temp.tv_sec = abstime->tv_sec;
|
||||
temp.tv_nsec = abstime->tv_usec * 1000;
|
||||
return waitForTime(&temp);
|
||||
}
|
||||
/**
|
||||
* Waits forever until the condition occurs.
|
||||
* Returns 0 if condition occurs, or an error code otherwise.
|
||||
*/
|
||||
int waitForever() const {
|
||||
assert(mutex_);
|
||||
pthread_mutex_t* mutexImpl = reinterpret_cast<pthread_mutex_t*>(mutex_->getUnderlyingImpl());
|
||||
assert(mutexImpl);
|
||||
return pthread_cond_wait(&pthread_cond_, mutexImpl);
|
||||
}
|
||||
|
||||
void notify() {
|
||||
// XXX Need to assert that caller owns mutex
|
||||
int iret = pthread_cond_signal(&pthread_cond_);
|
||||
THRIFT_UNUSED_VARIABLE(iret);
|
||||
assert(iret == 0);
|
||||
}
|
||||
|
||||
void notifyAll() {
|
||||
// XXX Need to assert that caller owns mutex
|
||||
int iret = pthread_cond_broadcast(&pthread_cond_);
|
||||
THRIFT_UNUSED_VARIABLE(iret);
|
||||
assert(iret == 0);
|
||||
}
|
||||
|
||||
private:
|
||||
void init(Mutex* mutex) {
|
||||
mutex_ = mutex;
|
||||
|
||||
if (pthread_cond_init(&pthread_cond_, NULL) == 0) {
|
||||
condInitialized_ = true;
|
||||
}
|
||||
|
||||
if (!condInitialized_) {
|
||||
cleanup();
|
||||
throw SystemResourceException();
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup() {
|
||||
if (condInitialized_) {
|
||||
condInitialized_ = false;
|
||||
int iret = pthread_cond_destroy(&pthread_cond_);
|
||||
THRIFT_UNUSED_VARIABLE(iret);
|
||||
assert(iret == 0);
|
||||
}
|
||||
}
|
||||
|
||||
scoped_ptr<Mutex> ownedMutex_;
|
||||
Mutex* mutex_;
|
||||
|
||||
mutable pthread_cond_t pthread_cond_;
|
||||
mutable bool condInitialized_;
|
||||
};
|
||||
|
||||
Monitor::Monitor() : impl_(new Monitor::Impl()) {
|
||||
}
|
||||
Monitor::Monitor(Mutex* mutex) : impl_(new Monitor::Impl(mutex)) {
|
||||
}
|
||||
Monitor::Monitor(Monitor* monitor) : impl_(new Monitor::Impl(monitor)) {
|
||||
}
|
||||
|
||||
Monitor::~Monitor() {
|
||||
delete impl_;
|
||||
}
|
||||
|
||||
Mutex& Monitor::mutex() const {
|
||||
return impl_->mutex();
|
||||
}
|
||||
|
||||
void Monitor::lock() const {
|
||||
impl_->lock();
|
||||
}
|
||||
|
||||
void Monitor::unlock() const {
|
||||
impl_->unlock();
|
||||
}
|
||||
|
||||
void Monitor::wait(int64_t timeout) const {
|
||||
impl_->wait(timeout);
|
||||
}
|
||||
|
||||
int Monitor::waitForTime(const THRIFT_TIMESPEC* abstime) const {
|
||||
return impl_->waitForTime(abstime);
|
||||
}
|
||||
|
||||
int Monitor::waitForTime(const timeval* abstime) const {
|
||||
return impl_->waitForTime(abstime);
|
||||
}
|
||||
|
||||
int Monitor::waitForTimeRelative(int64_t timeout_ms) const {
|
||||
return impl_->waitForTimeRelative(timeout_ms);
|
||||
}
|
||||
|
||||
int Monitor::waitForever() const {
|
||||
return impl_->waitForever();
|
||||
}
|
||||
|
||||
void Monitor::notify() const {
|
||||
impl_->notify();
|
||||
}
|
||||
|
||||
void Monitor::notifyAll() const {
|
||||
impl_->notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
133
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/Monitor.h
generated
vendored
Normal file
133
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/Monitor.h
generated
vendored
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_CONCURRENCY_MONITOR_H_
|
||||
#define _THRIFT_CONCURRENCY_MONITOR_H_ 1
|
||||
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <thrift/concurrency/Exception.h>
|
||||
#include <thrift/concurrency/Mutex.h>
|
||||
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
/**
|
||||
* A monitor is a combination mutex and condition-event. Waiting and
|
||||
* notifying condition events requires that the caller own the mutex. Mutex
|
||||
* lock and unlock operations can be performed independently of condition
|
||||
* events. This is more or less analogous to java.lang.Object multi-thread
|
||||
* operations.
|
||||
*
|
||||
* Note the Monitor can create a new, internal mutex; alternatively, a
|
||||
* separate Mutex can be passed in and the Monitor will re-use it without
|
||||
* taking ownership. It's the user's responsibility to make sure that the
|
||||
* Mutex is not deallocated before the Monitor.
|
||||
*
|
||||
* Note that all methods are const. Monitors implement logical constness, not
|
||||
* bit constness. This allows const methods to call monitor methods without
|
||||
* needing to cast away constness or change to non-const signatures.
|
||||
*
|
||||
* @version $Id:$
|
||||
*/
|
||||
class Monitor : boost::noncopyable {
|
||||
public:
|
||||
/** Creates a new mutex, and takes ownership of it. */
|
||||
Monitor();
|
||||
|
||||
/** Uses the provided mutex without taking ownership. */
|
||||
explicit Monitor(Mutex* mutex);
|
||||
|
||||
/** Uses the mutex inside the provided Monitor without taking ownership. */
|
||||
explicit Monitor(Monitor* monitor);
|
||||
|
||||
/** Deallocates the mutex only if we own it. */
|
||||
virtual ~Monitor();
|
||||
|
||||
Mutex& mutex() const;
|
||||
|
||||
virtual void lock() const;
|
||||
|
||||
virtual void unlock() const;
|
||||
|
||||
/**
|
||||
* Waits a maximum of the specified timeout in milliseconds for the condition
|
||||
* to occur, or waits forever if timeout_ms == 0.
|
||||
*
|
||||
* Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
|
||||
*/
|
||||
int waitForTimeRelative(int64_t timeout_ms) const;
|
||||
|
||||
/**
|
||||
* Waits until the absolute time specified using struct THRIFT_TIMESPEC.
|
||||
* Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
|
||||
*/
|
||||
int waitForTime(const THRIFT_TIMESPEC* abstime) const;
|
||||
|
||||
/**
|
||||
* Waits until the absolute time specified using struct timeval.
|
||||
* Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
|
||||
*/
|
||||
int waitForTime(const struct timeval* abstime) const;
|
||||
|
||||
/**
|
||||
* Waits forever until the condition occurs.
|
||||
* Returns 0 if condition occurs, or an error code otherwise.
|
||||
*/
|
||||
int waitForever() const;
|
||||
|
||||
/**
|
||||
* Exception-throwing version of waitForTimeRelative(), called simply
|
||||
* wait(int64) for historical reasons. Timeout is in milliseconds.
|
||||
*
|
||||
* If the condition occurs, this function returns cleanly; on timeout or
|
||||
* error an exception is thrown.
|
||||
*/
|
||||
void wait(int64_t timeout_ms = 0LL) const;
|
||||
|
||||
/** Wakes up one thread waiting on this monitor. */
|
||||
virtual void notify() const;
|
||||
|
||||
/** Wakes up all waiting threads on this monitor. */
|
||||
virtual void notifyAll() const;
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
|
||||
Impl* impl_;
|
||||
};
|
||||
|
||||
class Synchronized {
|
||||
public:
|
||||
Synchronized(const Monitor* monitor) : g(monitor->mutex()) {}
|
||||
Synchronized(const Monitor& monitor) : g(monitor.mutex()) {}
|
||||
|
||||
private:
|
||||
Guard g;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
||||
|
||||
#endif // #ifndef _THRIFT_CONCURRENCY_MONITOR_H_
|
373
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/Mutex.cpp
generated
vendored
Normal file
373
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/Mutex.cpp
generated
vendored
Normal file
|
@ -0,0 +1,373 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/thrift-config.h>
|
||||
|
||||
#include <thrift/Thrift.h>
|
||||
#include <thrift/concurrency/Mutex.h>
|
||||
#include <thrift/concurrency/Util.h>
|
||||
|
||||
#include <assert.h>
|
||||
#ifdef HAVE_PTHREAD_H
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
|
||||
using boost::shared_ptr;
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
#ifndef THRIFT_NO_CONTENTION_PROFILING
|
||||
|
||||
static int32_t mutexProfilingCounter = 0;
|
||||
static int32_t mutexProfilingSampleRate = 0;
|
||||
static MutexWaitCallback mutexProfilingCallback = 0;
|
||||
|
||||
void enableMutexProfiling(int32_t profilingSampleRate, MutexWaitCallback callback) {
|
||||
mutexProfilingSampleRate = profilingSampleRate;
|
||||
mutexProfilingCallback = callback;
|
||||
}
|
||||
|
||||
#define PROFILE_MUTEX_START_LOCK() int64_t _lock_startTime = maybeGetProfilingStartTime();
|
||||
|
||||
#define PROFILE_MUTEX_NOT_LOCKED() \
|
||||
do { \
|
||||
if (_lock_startTime > 0) { \
|
||||
int64_t endTime = Util::currentTimeUsec(); \
|
||||
(*mutexProfilingCallback)(this, endTime - _lock_startTime); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PROFILE_MUTEX_LOCKED() \
|
||||
do { \
|
||||
profileTime_ = _lock_startTime; \
|
||||
if (profileTime_ > 0) { \
|
||||
profileTime_ = Util::currentTimeUsec() - profileTime_; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PROFILE_MUTEX_START_UNLOCK() \
|
||||
int64_t _temp_profileTime = profileTime_; \
|
||||
profileTime_ = 0;
|
||||
|
||||
#define PROFILE_MUTEX_UNLOCKED() \
|
||||
do { \
|
||||
if (_temp_profileTime > 0) { \
|
||||
(*mutexProfilingCallback)(this, _temp_profileTime); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static inline int64_t maybeGetProfilingStartTime() {
|
||||
if (mutexProfilingSampleRate && mutexProfilingCallback) {
|
||||
// This block is unsynchronized, but should produce a reasonable sampling
|
||||
// rate on most architectures. The main race conditions are the gap
|
||||
// between the decrement and the test, the non-atomicity of decrement, and
|
||||
// potential caching of different values at different CPUs.
|
||||
//
|
||||
// - if two decrements race, the likeliest result is that the counter
|
||||
// decrements slowly (perhaps much more slowly) than intended.
|
||||
//
|
||||
// - many threads could potentially decrement before resetting the counter
|
||||
// to its large value, causing each additional incoming thread to
|
||||
// profile every call. This situation is unlikely to persist for long
|
||||
// as the critical gap is quite short, but profiling could be bursty.
|
||||
sig_atomic_t localValue = --mutexProfilingCounter;
|
||||
if (localValue <= 0) {
|
||||
mutexProfilingCounter = mutexProfilingSampleRate;
|
||||
return Util::currentTimeUsec();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#define PROFILE_MUTEX_START_LOCK()
|
||||
#define PROFILE_MUTEX_NOT_LOCKED()
|
||||
#define PROFILE_MUTEX_LOCKED()
|
||||
#define PROFILE_MUTEX_START_UNLOCK()
|
||||
#define PROFILE_MUTEX_UNLOCKED()
|
||||
#endif // THRIFT_NO_CONTENTION_PROFILING
|
||||
|
||||
/**
|
||||
* Implementation of Mutex class using POSIX mutex
|
||||
*
|
||||
* @version $Id:$
|
||||
*/
|
||||
class Mutex::impl {
|
||||
public:
|
||||
impl(Initializer init) : initialized_(false) {
|
||||
#ifndef THRIFT_NO_CONTENTION_PROFILING
|
||||
profileTime_ = 0;
|
||||
#endif
|
||||
init(&pthread_mutex_);
|
||||
initialized_ = true;
|
||||
}
|
||||
|
||||
~impl() {
|
||||
if (initialized_) {
|
||||
initialized_ = false;
|
||||
int ret = pthread_mutex_destroy(&pthread_mutex_);
|
||||
THRIFT_UNUSED_VARIABLE(ret);
|
||||
assert(ret == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void lock() const {
|
||||
PROFILE_MUTEX_START_LOCK();
|
||||
pthread_mutex_lock(&pthread_mutex_);
|
||||
PROFILE_MUTEX_LOCKED();
|
||||
}
|
||||
|
||||
bool trylock() const { return (0 == pthread_mutex_trylock(&pthread_mutex_)); }
|
||||
|
||||
bool timedlock(int64_t milliseconds) const {
|
||||
#if defined(_POSIX_TIMEOUTS) && _POSIX_TIMEOUTS >= 200112L
|
||||
PROFILE_MUTEX_START_LOCK();
|
||||
|
||||
struct THRIFT_TIMESPEC ts;
|
||||
Util::toTimespec(ts, milliseconds + Util::currentTime());
|
||||
int ret = pthread_mutex_timedlock(&pthread_mutex_, &ts);
|
||||
if (ret == 0) {
|
||||
PROFILE_MUTEX_LOCKED();
|
||||
return true;
|
||||
}
|
||||
|
||||
PROFILE_MUTEX_NOT_LOCKED();
|
||||
return false;
|
||||
#else
|
||||
/* Otherwise follow solution used by Mono for Android */
|
||||
struct THRIFT_TIMESPEC sleepytime, now, to;
|
||||
|
||||
/* This is just to avoid a completely busy wait */
|
||||
sleepytime.tv_sec = 0;
|
||||
sleepytime.tv_nsec = 10000000L; /* 10ms */
|
||||
|
||||
Util::toTimespec(to, milliseconds + Util::currentTime());
|
||||
|
||||
while ((trylock()) == false) {
|
||||
Util::toTimespec(now, Util::currentTime());
|
||||
if (now.tv_sec >= to.tv_sec && now.tv_nsec >= to.tv_nsec) {
|
||||
return false;
|
||||
}
|
||||
nanosleep(&sleepytime, NULL);
|
||||
}
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void unlock() const {
|
||||
PROFILE_MUTEX_START_UNLOCK();
|
||||
pthread_mutex_unlock(&pthread_mutex_);
|
||||
PROFILE_MUTEX_UNLOCKED();
|
||||
}
|
||||
|
||||
void* getUnderlyingImpl() const { return (void*)&pthread_mutex_; }
|
||||
|
||||
private:
|
||||
mutable pthread_mutex_t pthread_mutex_;
|
||||
mutable bool initialized_;
|
||||
#ifndef THRIFT_NO_CONTENTION_PROFILING
|
||||
mutable int64_t profileTime_;
|
||||
#endif
|
||||
};
|
||||
|
||||
Mutex::Mutex(Initializer init) : impl_(new Mutex::impl(init)) {
|
||||
}
|
||||
|
||||
void* Mutex::getUnderlyingImpl() const {
|
||||
return impl_->getUnderlyingImpl();
|
||||
}
|
||||
|
||||
void Mutex::lock() const {
|
||||
impl_->lock();
|
||||
}
|
||||
|
||||
bool Mutex::trylock() const {
|
||||
return impl_->trylock();
|
||||
}
|
||||
|
||||
bool Mutex::timedlock(int64_t ms) const {
|
||||
return impl_->timedlock(ms);
|
||||
}
|
||||
|
||||
void Mutex::unlock() const {
|
||||
impl_->unlock();
|
||||
}
|
||||
|
||||
void Mutex::DEFAULT_INITIALIZER(void* arg) {
|
||||
pthread_mutex_t* pthread_mutex = (pthread_mutex_t*)arg;
|
||||
int ret = pthread_mutex_init(pthread_mutex, NULL);
|
||||
THRIFT_UNUSED_VARIABLE(ret);
|
||||
assert(ret == 0);
|
||||
}
|
||||
|
||||
#if defined(PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP) \
|
||||
|| defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
|
||||
static void init_with_kind(pthread_mutex_t* mutex, int kind) {
|
||||
pthread_mutexattr_t mutexattr;
|
||||
int ret = pthread_mutexattr_init(&mutexattr);
|
||||
assert(ret == 0);
|
||||
|
||||
// Apparently, this can fail. Should we really be aborting?
|
||||
ret = pthread_mutexattr_settype(&mutexattr, kind);
|
||||
assert(ret == 0);
|
||||
|
||||
ret = pthread_mutex_init(mutex, &mutexattr);
|
||||
assert(ret == 0);
|
||||
|
||||
ret = pthread_mutexattr_destroy(&mutexattr);
|
||||
assert(ret == 0);
|
||||
THRIFT_UNUSED_VARIABLE(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
|
||||
void Mutex::ADAPTIVE_INITIALIZER(void* arg) {
|
||||
// From mysql source: mysys/my_thr_init.c
|
||||
// Set mutex type to "fast" a.k.a "adaptive"
|
||||
//
|
||||
// In this case the thread may steal the mutex from some other thread
|
||||
// that is waiting for the same mutex. This will save us some
|
||||
// context switches but may cause a thread to 'starve forever' while
|
||||
// waiting for the mutex (not likely if the code within the mutex is
|
||||
// short).
|
||||
init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_ADAPTIVE_NP);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
|
||||
void Mutex::RECURSIVE_INITIALIZER(void* arg) {
|
||||
init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_RECURSIVE_NP);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Implementation of ReadWriteMutex class using POSIX rw lock
|
||||
*
|
||||
* @version $Id:$
|
||||
*/
|
||||
class ReadWriteMutex::impl {
|
||||
public:
|
||||
impl() : initialized_(false) {
|
||||
#ifndef THRIFT_NO_CONTENTION_PROFILING
|
||||
profileTime_ = 0;
|
||||
#endif
|
||||
int ret = pthread_rwlock_init(&rw_lock_, NULL);
|
||||
THRIFT_UNUSED_VARIABLE(ret);
|
||||
assert(ret == 0);
|
||||
initialized_ = true;
|
||||
}
|
||||
|
||||
~impl() {
|
||||
if (initialized_) {
|
||||
initialized_ = false;
|
||||
int ret = pthread_rwlock_destroy(&rw_lock_);
|
||||
THRIFT_UNUSED_VARIABLE(ret);
|
||||
assert(ret == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void acquireRead() const {
|
||||
PROFILE_MUTEX_START_LOCK();
|
||||
pthread_rwlock_rdlock(&rw_lock_);
|
||||
PROFILE_MUTEX_NOT_LOCKED(); // not exclusive, so use not-locked path
|
||||
}
|
||||
|
||||
void acquireWrite() const {
|
||||
PROFILE_MUTEX_START_LOCK();
|
||||
pthread_rwlock_wrlock(&rw_lock_);
|
||||
PROFILE_MUTEX_LOCKED();
|
||||
}
|
||||
|
||||
bool attemptRead() const { return !pthread_rwlock_tryrdlock(&rw_lock_); }
|
||||
|
||||
bool attemptWrite() const { return !pthread_rwlock_trywrlock(&rw_lock_); }
|
||||
|
||||
void release() const {
|
||||
PROFILE_MUTEX_START_UNLOCK();
|
||||
pthread_rwlock_unlock(&rw_lock_);
|
||||
PROFILE_MUTEX_UNLOCKED();
|
||||
}
|
||||
|
||||
private:
|
||||
mutable pthread_rwlock_t rw_lock_;
|
||||
mutable bool initialized_;
|
||||
#ifndef THRIFT_NO_CONTENTION_PROFILING
|
||||
mutable int64_t profileTime_;
|
||||
#endif
|
||||
};
|
||||
|
||||
ReadWriteMutex::ReadWriteMutex() : impl_(new ReadWriteMutex::impl()) {
|
||||
}
|
||||
|
||||
void ReadWriteMutex::acquireRead() const {
|
||||
impl_->acquireRead();
|
||||
}
|
||||
|
||||
void ReadWriteMutex::acquireWrite() const {
|
||||
impl_->acquireWrite();
|
||||
}
|
||||
|
||||
bool ReadWriteMutex::attemptRead() const {
|
||||
return impl_->attemptRead();
|
||||
}
|
||||
|
||||
bool ReadWriteMutex::attemptWrite() const {
|
||||
return impl_->attemptWrite();
|
||||
}
|
||||
|
||||
void ReadWriteMutex::release() const {
|
||||
impl_->release();
|
||||
}
|
||||
|
||||
NoStarveReadWriteMutex::NoStarveReadWriteMutex() : writerWaiting_(false) {
|
||||
}
|
||||
|
||||
void NoStarveReadWriteMutex::acquireRead() const {
|
||||
if (writerWaiting_) {
|
||||
// writer is waiting, block on the writer's mutex until he's done with it
|
||||
mutex_.lock();
|
||||
mutex_.unlock();
|
||||
}
|
||||
|
||||
ReadWriteMutex::acquireRead();
|
||||
}
|
||||
|
||||
void NoStarveReadWriteMutex::acquireWrite() const {
|
||||
// if we can acquire the rwlock the easy way, we're done
|
||||
if (attemptWrite()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// failed to get the rwlock, do it the hard way:
|
||||
// locking the mutex and setting writerWaiting will cause all new readers to
|
||||
// block on the mutex rather than on the rwlock.
|
||||
mutex_.lock();
|
||||
writerWaiting_ = true;
|
||||
ReadWriteMutex::acquireWrite();
|
||||
writerWaiting_ = false;
|
||||
mutex_.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
180
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/Mutex.h
generated
vendored
Normal file
180
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/Mutex.h
generated
vendored
Normal file
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_CONCURRENCY_MUTEX_H_
|
||||
#define _THRIFT_CONCURRENCY_MUTEX_H_ 1
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
#ifndef THRIFT_NO_CONTENTION_PROFILING
|
||||
|
||||
/**
|
||||
* Determines if the Thrift Mutex and ReadWriteMutex classes will attempt to
|
||||
* profile their blocking acquire methods. If this value is set to non-zero,
|
||||
* Thrift will attempt to invoke the callback once every profilingSampleRate
|
||||
* times. However, as the sampling is not synchronized the rate is not
|
||||
* guranateed, and could be subject to big bursts and swings. Please ensure
|
||||
* your sampling callback is as performant as your application requires.
|
||||
*
|
||||
* The callback will get called with the wait time taken to lock the mutex in
|
||||
* usec and a (void*) that uniquely identifies the Mutex (or ReadWriteMutex)
|
||||
* being locked.
|
||||
*
|
||||
* The enableMutexProfiling() function is unsynchronized; calling this function
|
||||
* while profiling is already enabled may result in race conditions. On
|
||||
* architectures where a pointer assignment is atomic, this is safe but there
|
||||
* is no guarantee threads will agree on a single callback within any
|
||||
* particular time period.
|
||||
*/
|
||||
typedef void (*MutexWaitCallback)(const void* id, int64_t waitTimeMicros);
|
||||
void enableMutexProfiling(int32_t profilingSampleRate, MutexWaitCallback callback);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A simple mutex class
|
||||
*
|
||||
* @version $Id:$
|
||||
*/
|
||||
class Mutex {
|
||||
public:
|
||||
typedef void (*Initializer)(void*);
|
||||
|
||||
Mutex(Initializer init = DEFAULT_INITIALIZER);
|
||||
virtual ~Mutex() {}
|
||||
virtual void lock() const;
|
||||
virtual bool trylock() const;
|
||||
virtual bool timedlock(int64_t milliseconds) const;
|
||||
virtual void unlock() const;
|
||||
|
||||
void* getUnderlyingImpl() const;
|
||||
|
||||
static void DEFAULT_INITIALIZER(void*);
|
||||
static void ADAPTIVE_INITIALIZER(void*);
|
||||
static void RECURSIVE_INITIALIZER(void*);
|
||||
|
||||
private:
|
||||
class impl;
|
||||
boost::shared_ptr<impl> impl_;
|
||||
};
|
||||
|
||||
class ReadWriteMutex {
|
||||
public:
|
||||
ReadWriteMutex();
|
||||
virtual ~ReadWriteMutex() {}
|
||||
|
||||
// these get the lock and block until it is done successfully
|
||||
virtual void acquireRead() const;
|
||||
virtual void acquireWrite() const;
|
||||
|
||||
// these attempt to get the lock, returning false immediately if they fail
|
||||
virtual bool attemptRead() const;
|
||||
virtual bool attemptWrite() const;
|
||||
|
||||
// this releases both read and write locks
|
||||
virtual void release() const;
|
||||
|
||||
private:
|
||||
class impl;
|
||||
boost::shared_ptr<impl> impl_;
|
||||
};
|
||||
|
||||
/**
|
||||
* A ReadWriteMutex that guarantees writers will not be starved by readers:
|
||||
* When a writer attempts to acquire the mutex, all new readers will be
|
||||
* blocked from acquiring the mutex until the writer has acquired and
|
||||
* released it. In some operating systems, this may already be guaranteed
|
||||
* by a regular ReadWriteMutex.
|
||||
*/
|
||||
class NoStarveReadWriteMutex : public ReadWriteMutex {
|
||||
public:
|
||||
NoStarveReadWriteMutex();
|
||||
|
||||
virtual void acquireRead() const;
|
||||
virtual void acquireWrite() const;
|
||||
|
||||
private:
|
||||
Mutex mutex_;
|
||||
mutable volatile bool writerWaiting_;
|
||||
};
|
||||
|
||||
class Guard : boost::noncopyable {
|
||||
public:
|
||||
Guard(const Mutex& value, int64_t timeout = 0) : mutex_(&value) {
|
||||
if (timeout == 0) {
|
||||
value.lock();
|
||||
} else if (timeout < 0) {
|
||||
if (!value.trylock()) {
|
||||
mutex_ = NULL;
|
||||
}
|
||||
} else {
|
||||
if (!value.timedlock(timeout)) {
|
||||
mutex_ = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
~Guard() {
|
||||
if (mutex_) {
|
||||
mutex_->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
operator bool() const { return (mutex_ != NULL); }
|
||||
|
||||
private:
|
||||
const Mutex* mutex_;
|
||||
};
|
||||
|
||||
// Can be used as second argument to RWGuard to make code more readable
|
||||
// as to whether we're doing acquireRead() or acquireWrite().
|
||||
enum RWGuardType { RW_READ = 0, RW_WRITE = 1 };
|
||||
|
||||
class RWGuard : boost::noncopyable {
|
||||
public:
|
||||
RWGuard(const ReadWriteMutex& value, bool write = false) : rw_mutex_(value) {
|
||||
if (write) {
|
||||
rw_mutex_.acquireWrite();
|
||||
} else {
|
||||
rw_mutex_.acquireRead();
|
||||
}
|
||||
}
|
||||
|
||||
RWGuard(const ReadWriteMutex& value, RWGuardType type) : rw_mutex_(value) {
|
||||
if (type == RW_WRITE) {
|
||||
rw_mutex_.acquireWrite();
|
||||
} else {
|
||||
rw_mutex_.acquireRead();
|
||||
}
|
||||
}
|
||||
~RWGuard() { rw_mutex_.release(); }
|
||||
|
||||
private:
|
||||
const ReadWriteMutex& rw_mutex_;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
||||
|
||||
#endif // #ifndef _THRIFT_CONCURRENCY_MUTEX_H_
|
52
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/PlatformThreadFactory.h
generated
vendored
Normal file
52
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/PlatformThreadFactory.h
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_CONCURRENCY_PLATFORMTHREADFACTORY_H_
|
||||
#define _THRIFT_CONCURRENCY_PLATFORMTHREADFACTORY_H_ 1
|
||||
|
||||
// clang-format off
|
||||
#include <thrift/thrift-config.h>
|
||||
#if USE_BOOST_THREAD
|
||||
# include <thrift/concurrency/BoostThreadFactory.h>
|
||||
#elif USE_STD_THREAD
|
||||
# include <thrift/concurrency/StdThreadFactory.h>
|
||||
#else
|
||||
# include <thrift/concurrency/PosixThreadFactory.h>
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
// clang-format off
|
||||
#if USE_BOOST_THREAD
|
||||
typedef BoostThreadFactory PlatformThreadFactory;
|
||||
#elif USE_STD_THREAD
|
||||
typedef StdThreadFactory PlatformThreadFactory;
|
||||
#else
|
||||
typedef PosixThreadFactory PlatformThreadFactory;
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
||||
|
||||
#endif // #ifndef _THRIFT_CONCURRENCY_PLATFORMTHREADFACTORY_H_
|
317
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/PosixThreadFactory.cpp
generated
vendored
Normal file
317
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/PosixThreadFactory.cpp
generated
vendored
Normal file
|
@ -0,0 +1,317 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/thrift-config.h>
|
||||
|
||||
#include <thrift/concurrency/PosixThreadFactory.h>
|
||||
#include <thrift/concurrency/Exception.h>
|
||||
|
||||
#if GOOGLE_PERFTOOLS_REGISTER_THREAD
|
||||
#include <google/profiler.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/weak_ptr.hpp>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
using boost::shared_ptr;
|
||||
using boost::weak_ptr;
|
||||
|
||||
/**
|
||||
* The POSIX thread class.
|
||||
*
|
||||
* @version $Id:$
|
||||
*/
|
||||
class PthreadThread : public Thread {
|
||||
public:
|
||||
enum STATE { uninitialized, starting, started, stopping, stopped };
|
||||
|
||||
static const int MB = 1024 * 1024;
|
||||
|
||||
static void* threadMain(void* arg);
|
||||
|
||||
private:
|
||||
pthread_t pthread_;
|
||||
STATE state_;
|
||||
int policy_;
|
||||
int priority_;
|
||||
int stackSize_;
|
||||
weak_ptr<PthreadThread> self_;
|
||||
bool detached_;
|
||||
|
||||
public:
|
||||
PthreadThread(int policy,
|
||||
int priority,
|
||||
int stackSize,
|
||||
bool detached,
|
||||
shared_ptr<Runnable> runnable)
|
||||
:
|
||||
|
||||
#ifndef _WIN32
|
||||
pthread_(0),
|
||||
#endif // _WIN32
|
||||
|
||||
state_(uninitialized),
|
||||
policy_(policy),
|
||||
priority_(priority),
|
||||
stackSize_(stackSize),
|
||||
detached_(detached) {
|
||||
|
||||
this->Thread::runnable(runnable);
|
||||
}
|
||||
|
||||
~PthreadThread() {
|
||||
/* Nothing references this thread, if is is not detached, do a join
|
||||
now, otherwise the thread-id and, possibly, other resources will
|
||||
be leaked. */
|
||||
if (!detached_) {
|
||||
try {
|
||||
join();
|
||||
} catch (...) {
|
||||
// We're really hosed.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void start() {
|
||||
if (state_ != uninitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_attr_t thread_attr;
|
||||
if (pthread_attr_init(&thread_attr) != 0) {
|
||||
throw SystemResourceException("pthread_attr_init failed");
|
||||
}
|
||||
|
||||
if (pthread_attr_setdetachstate(&thread_attr,
|
||||
detached_ ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE)
|
||||
!= 0) {
|
||||
throw SystemResourceException("pthread_attr_setdetachstate failed");
|
||||
}
|
||||
|
||||
// Set thread stack size
|
||||
if (pthread_attr_setstacksize(&thread_attr, MB * stackSize_) != 0) {
|
||||
throw SystemResourceException("pthread_attr_setstacksize failed");
|
||||
}
|
||||
|
||||
// Set thread policy
|
||||
#ifdef _WIN32
|
||||
// WIN32 Pthread implementation doesn't seem to support sheduling policies other then
|
||||
// PosixThreadFactory::OTHER - runtime error
|
||||
policy_ = PosixThreadFactory::OTHER;
|
||||
#endif
|
||||
|
||||
#if _POSIX_THREAD_PRIORITY_SCHEDULING > 0
|
||||
if (pthread_attr_setschedpolicy(&thread_attr, policy_) != 0) {
|
||||
throw SystemResourceException("pthread_attr_setschedpolicy failed");
|
||||
}
|
||||
#endif
|
||||
|
||||
struct sched_param sched_param;
|
||||
sched_param.sched_priority = priority_;
|
||||
|
||||
// Set thread priority
|
||||
if (pthread_attr_setschedparam(&thread_attr, &sched_param) != 0) {
|
||||
throw SystemResourceException("pthread_attr_setschedparam failed");
|
||||
}
|
||||
|
||||
// Create reference
|
||||
shared_ptr<PthreadThread>* selfRef = new shared_ptr<PthreadThread>();
|
||||
*selfRef = self_.lock();
|
||||
|
||||
state_ = starting;
|
||||
|
||||
if (pthread_create(&pthread_, &thread_attr, threadMain, (void*)selfRef) != 0) {
|
||||
throw SystemResourceException("pthread_create failed");
|
||||
}
|
||||
}
|
||||
|
||||
void join() {
|
||||
if (!detached_ && state_ != uninitialized) {
|
||||
void* ignore;
|
||||
/* XXX
|
||||
If join fails it is most likely due to the fact
|
||||
that the last reference was the thread itself and cannot
|
||||
join. This results in leaked threads and will eventually
|
||||
cause the process to run out of thread resources.
|
||||
We're beyond the point of throwing an exception. Not clear how
|
||||
best to handle this. */
|
||||
int res = pthread_join(pthread_, &ignore);
|
||||
detached_ = (res == 0);
|
||||
if (res != 0) {
|
||||
GlobalOutput.printf("PthreadThread::join(): fail with code %d", res);
|
||||
}
|
||||
} else {
|
||||
GlobalOutput.printf("PthreadThread::join(): detached thread");
|
||||
}
|
||||
}
|
||||
|
||||
Thread::id_t getId() {
|
||||
|
||||
#ifndef _WIN32
|
||||
return (Thread::id_t)pthread_;
|
||||
#else
|
||||
return (Thread::id_t)pthread_.p;
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
shared_ptr<Runnable> runnable() const { return Thread::runnable(); }
|
||||
|
||||
void runnable(shared_ptr<Runnable> value) { Thread::runnable(value); }
|
||||
|
||||
void weakRef(shared_ptr<PthreadThread> self) {
|
||||
assert(self.get() == this);
|
||||
self_ = weak_ptr<PthreadThread>(self);
|
||||
}
|
||||
};
|
||||
|
||||
void* PthreadThread::threadMain(void* arg) {
|
||||
shared_ptr<PthreadThread> thread = *(shared_ptr<PthreadThread>*)arg;
|
||||
delete reinterpret_cast<shared_ptr<PthreadThread>*>(arg);
|
||||
|
||||
if (thread == NULL) {
|
||||
return (void*)0;
|
||||
}
|
||||
|
||||
if (thread->state_ != starting) {
|
||||
return (void*)0;
|
||||
}
|
||||
|
||||
#if GOOGLE_PERFTOOLS_REGISTER_THREAD
|
||||
ProfilerRegisterThread();
|
||||
#endif
|
||||
|
||||
thread->state_ = started;
|
||||
thread->runnable()->run();
|
||||
if (thread->state_ != stopping && thread->state_ != stopped) {
|
||||
thread->state_ = stopping;
|
||||
}
|
||||
|
||||
return (void*)0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts generic posix thread schedule policy enums into pthread
|
||||
* API values.
|
||||
*/
|
||||
static int toPthreadPolicy(PosixThreadFactory::POLICY policy) {
|
||||
switch (policy) {
|
||||
case PosixThreadFactory::OTHER:
|
||||
return SCHED_OTHER;
|
||||
case PosixThreadFactory::FIFO:
|
||||
return SCHED_FIFO;
|
||||
case PosixThreadFactory::ROUND_ROBIN:
|
||||
return SCHED_RR;
|
||||
}
|
||||
return SCHED_OTHER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts relative thread priorities to absolute value based on posix
|
||||
* thread scheduler policy
|
||||
*
|
||||
* The idea is simply to divide up the priority range for the given policy
|
||||
* into the correpsonding relative priority level (lowest..highest) and
|
||||
* then pro-rate accordingly.
|
||||
*/
|
||||
static int toPthreadPriority(PosixThreadFactory::POLICY policy, PosixThreadFactory::PRIORITY priority) {
|
||||
int pthread_policy = toPthreadPolicy(policy);
|
||||
int min_priority = 0;
|
||||
int max_priority = 0;
|
||||
#ifdef HAVE_SCHED_GET_PRIORITY_MIN
|
||||
min_priority = sched_get_priority_min(pthread_policy);
|
||||
#endif
|
||||
#ifdef HAVE_SCHED_GET_PRIORITY_MAX
|
||||
max_priority = sched_get_priority_max(pthread_policy);
|
||||
#endif
|
||||
int quanta = (PosixThreadFactory::HIGHEST - PosixThreadFactory::LOWEST) + 1;
|
||||
float stepsperquanta = (float)(max_priority - min_priority) / quanta;
|
||||
|
||||
if (priority <= PosixThreadFactory::HIGHEST) {
|
||||
return (int)(min_priority + stepsperquanta * priority);
|
||||
} else {
|
||||
// should never get here for priority increments.
|
||||
assert(false);
|
||||
return (int)(min_priority + stepsperquanta * PosixThreadFactory::NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
PosixThreadFactory::PosixThreadFactory(POLICY policy,
|
||||
PRIORITY priority,
|
||||
int stackSize,
|
||||
bool detached)
|
||||
: ThreadFactory(detached),
|
||||
policy_(policy),
|
||||
priority_(priority),
|
||||
stackSize_(stackSize) {
|
||||
}
|
||||
|
||||
PosixThreadFactory::PosixThreadFactory(bool detached)
|
||||
: ThreadFactory(detached),
|
||||
policy_(ROUND_ROBIN),
|
||||
priority_(NORMAL),
|
||||
stackSize_(1) {
|
||||
}
|
||||
|
||||
shared_ptr<Thread> PosixThreadFactory::newThread(shared_ptr<Runnable> runnable) const {
|
||||
shared_ptr<PthreadThread> result
|
||||
= shared_ptr<PthreadThread>(new PthreadThread(toPthreadPolicy(policy_),
|
||||
toPthreadPriority(policy_, priority_),
|
||||
stackSize_,
|
||||
isDetached(),
|
||||
runnable));
|
||||
result->weakRef(result);
|
||||
runnable->thread(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
int PosixThreadFactory::getStackSize() const {
|
||||
return stackSize_;
|
||||
}
|
||||
|
||||
void PosixThreadFactory::setStackSize(int value) {
|
||||
stackSize_ = value;
|
||||
}
|
||||
|
||||
PosixThreadFactory::PRIORITY PosixThreadFactory::getPriority() const {
|
||||
return priority_;
|
||||
}
|
||||
|
||||
void PosixThreadFactory::setPriority(PRIORITY value) {
|
||||
priority_ = value;
|
||||
}
|
||||
|
||||
Thread::id_t PosixThreadFactory::getCurrentThreadId() const {
|
||||
#ifndef _WIN32
|
||||
return (Thread::id_t)pthread_self();
|
||||
#else
|
||||
return (Thread::id_t)pthread_self().p;
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
129
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/PosixThreadFactory.h
generated
vendored
Normal file
129
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/PosixThreadFactory.h
generated
vendored
Normal file
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_CONCURRENCY_POSIXTHREADFACTORY_H_
|
||||
#define _THRIFT_CONCURRENCY_POSIXTHREADFACTORY_H_ 1
|
||||
|
||||
#include <thrift/concurrency/Thread.h>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
/**
|
||||
* A thread factory to create posix threads
|
||||
*
|
||||
* @version $Id:$
|
||||
*/
|
||||
class PosixThreadFactory : public ThreadFactory {
|
||||
|
||||
public:
|
||||
/**
|
||||
* POSIX Thread scheduler policies
|
||||
*/
|
||||
enum POLICY { OTHER, FIFO, ROUND_ROBIN };
|
||||
|
||||
/**
|
||||
* POSIX Thread scheduler relative priorities,
|
||||
*
|
||||
* Absolute priority is determined by scheduler policy and OS. This
|
||||
* enumeration specifies relative priorities such that one can specify a
|
||||
* priority within a giving scheduler policy without knowing the absolute
|
||||
* value of the priority.
|
||||
*/
|
||||
enum PRIORITY {
|
||||
LOWEST = 0,
|
||||
LOWER = 1,
|
||||
LOW = 2,
|
||||
NORMAL = 3,
|
||||
HIGH = 4,
|
||||
HIGHER = 5,
|
||||
HIGHEST = 6,
|
||||
INCREMENT = 7,
|
||||
DECREMENT = 8
|
||||
};
|
||||
|
||||
/**
|
||||
* Posix thread (pthread) factory. All threads created by a factory are reference-counted
|
||||
* via boost::shared_ptr and boost::weak_ptr. The factory guarantees that threads and
|
||||
* the Runnable tasks they host will be properly cleaned up once the last strong reference
|
||||
* to both is given up.
|
||||
*
|
||||
* Threads are created with the specified policy, priority, stack-size and detachable-mode
|
||||
* detached means the thread is free-running and will release all system resources the
|
||||
* when it completes. A detachable thread is not joinable. The join method
|
||||
* of a detachable thread will return immediately with no error.
|
||||
*
|
||||
* By default threads are not joinable.
|
||||
*/
|
||||
PosixThreadFactory(POLICY policy = ROUND_ROBIN,
|
||||
PRIORITY priority = NORMAL,
|
||||
int stackSize = 1,
|
||||
bool detached = true);
|
||||
|
||||
/**
|
||||
* Provide a constructor compatible with the other factories
|
||||
* The default policy is POLICY::ROUND_ROBIN.
|
||||
* The default priority is PRIORITY::NORMAL.
|
||||
* The default stackSize is 1.
|
||||
*/
|
||||
PosixThreadFactory(bool detached);
|
||||
|
||||
// From ThreadFactory;
|
||||
boost::shared_ptr<Thread> newThread(boost::shared_ptr<Runnable> runnable) const;
|
||||
|
||||
// From ThreadFactory;
|
||||
Thread::id_t getCurrentThreadId() const;
|
||||
|
||||
/**
|
||||
* Gets stack size for newly created threads
|
||||
*
|
||||
* @return int size in megabytes
|
||||
*/
|
||||
virtual int getStackSize() const;
|
||||
|
||||
/**
|
||||
* Sets stack size for newly created threads
|
||||
*
|
||||
* @param value size in megabytes
|
||||
*/
|
||||
virtual void setStackSize(int value);
|
||||
|
||||
/**
|
||||
* Gets priority relative to current policy
|
||||
*/
|
||||
virtual PRIORITY getPriority() const;
|
||||
|
||||
/**
|
||||
* Sets priority relative to current policy
|
||||
*/
|
||||
virtual void setPriority(PRIORITY priority);
|
||||
|
||||
private:
|
||||
POLICY policy_;
|
||||
PRIORITY priority_;
|
||||
int stackSize_;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
||||
|
||||
#endif // #ifndef _THRIFT_CONCURRENCY_POSIXTHREADFACTORY_H_
|
213
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/StdMonitor.cpp
generated
vendored
Normal file
213
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/StdMonitor.cpp
generated
vendored
Normal file
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/thrift-config.h>
|
||||
|
||||
#include <thrift/concurrency/Monitor.h>
|
||||
#include <thrift/concurrency/Exception.h>
|
||||
#include <thrift/concurrency/Util.h>
|
||||
#include <thrift/transport/PlatformSocket.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <condition_variable>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
/**
|
||||
* Monitor implementation using the std thread library
|
||||
*
|
||||
* @version $Id:$
|
||||
*/
|
||||
class Monitor::Impl {
|
||||
|
||||
public:
|
||||
Impl() : ownedMutex_(new Mutex()), conditionVariable_(), mutex_(NULL) { init(ownedMutex_.get()); }
|
||||
|
||||
Impl(Mutex* mutex) : ownedMutex_(), conditionVariable_(), mutex_(NULL) { init(mutex); }
|
||||
|
||||
Impl(Monitor* monitor) : ownedMutex_(), conditionVariable_(), mutex_(NULL) {
|
||||
init(&(monitor->mutex()));
|
||||
}
|
||||
|
||||
Mutex& mutex() { return *mutex_; }
|
||||
void lock() { mutex_->lock(); }
|
||||
void unlock() { mutex_->unlock(); }
|
||||
|
||||
/**
|
||||
* Exception-throwing version of waitForTimeRelative(), called simply
|
||||
* wait(int64) for historical reasons. Timeout is in milliseconds.
|
||||
*
|
||||
* If the condition occurs, this function returns cleanly; on timeout or
|
||||
* error an exception is thrown.
|
||||
*/
|
||||
void wait(int64_t timeout_ms) {
|
||||
int result = waitForTimeRelative(timeout_ms);
|
||||
if (result == THRIFT_ETIMEDOUT) {
|
||||
throw TimedOutException();
|
||||
} else if (result != 0) {
|
||||
throw TException("Monitor::wait() failed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits until the specified timeout in milliseconds for the condition to
|
||||
* occur, or waits forever if timeout_ms == 0.
|
||||
*
|
||||
* Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
|
||||
*/
|
||||
int waitForTimeRelative(int64_t timeout_ms) {
|
||||
if (timeout_ms == 0LL) {
|
||||
return waitForever();
|
||||
}
|
||||
|
||||
assert(mutex_);
|
||||
std::timed_mutex* mutexImpl = static_cast<std::timed_mutex*>(mutex_->getUnderlyingImpl());
|
||||
assert(mutexImpl);
|
||||
|
||||
std::unique_lock<std::timed_mutex> lock(*mutexImpl, std::adopt_lock);
|
||||
bool timedout = (conditionVariable_.wait_for(lock, std::chrono::milliseconds(timeout_ms))
|
||||
== std::cv_status::timeout);
|
||||
lock.release();
|
||||
return (timedout ? THRIFT_ETIMEDOUT : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits until the absolute time specified using struct THRIFT_TIMESPEC.
|
||||
* Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
|
||||
*/
|
||||
int waitForTime(const THRIFT_TIMESPEC* abstime) {
|
||||
struct timeval temp;
|
||||
temp.tv_sec = static_cast<long>(abstime->tv_sec);
|
||||
temp.tv_usec = static_cast<long>(abstime->tv_nsec) / 1000;
|
||||
return waitForTime(&temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits until the absolute time specified using struct timeval.
|
||||
* Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
|
||||
*/
|
||||
int waitForTime(const struct timeval* abstime) {
|
||||
assert(mutex_);
|
||||
std::timed_mutex* mutexImpl = static_cast<std::timed_mutex*>(mutex_->getUnderlyingImpl());
|
||||
assert(mutexImpl);
|
||||
|
||||
struct timeval currenttime;
|
||||
Util::toTimeval(currenttime, Util::currentTime());
|
||||
|
||||
long tv_sec = static_cast<long>(abstime->tv_sec - currenttime.tv_sec);
|
||||
long tv_usec = static_cast<long>(abstime->tv_usec - currenttime.tv_usec);
|
||||
if (tv_sec < 0)
|
||||
tv_sec = 0;
|
||||
if (tv_usec < 0)
|
||||
tv_usec = 0;
|
||||
|
||||
std::unique_lock<std::timed_mutex> lock(*mutexImpl, std::adopt_lock);
|
||||
bool timedout = (conditionVariable_.wait_for(lock,
|
||||
std::chrono::seconds(tv_sec)
|
||||
+ std::chrono::microseconds(tv_usec))
|
||||
== std::cv_status::timeout);
|
||||
lock.release();
|
||||
return (timedout ? THRIFT_ETIMEDOUT : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits forever until the condition occurs.
|
||||
* Returns 0 if condition occurs, or an error code otherwise.
|
||||
*/
|
||||
int waitForever() {
|
||||
assert(mutex_);
|
||||
std::timed_mutex* mutexImpl = static_cast<std::timed_mutex*>(mutex_->getUnderlyingImpl());
|
||||
assert(mutexImpl);
|
||||
|
||||
std::unique_lock<std::timed_mutex> lock(*mutexImpl, std::adopt_lock);
|
||||
conditionVariable_.wait(lock);
|
||||
lock.release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void notify() { conditionVariable_.notify_one(); }
|
||||
|
||||
void notifyAll() { conditionVariable_.notify_all(); }
|
||||
|
||||
private:
|
||||
void init(Mutex* mutex) { mutex_ = mutex; }
|
||||
|
||||
const std::unique_ptr<Mutex> ownedMutex_;
|
||||
std::condition_variable_any conditionVariable_;
|
||||
Mutex* mutex_;
|
||||
};
|
||||
|
||||
Monitor::Monitor() : impl_(new Monitor::Impl()) {
|
||||
}
|
||||
Monitor::Monitor(Mutex* mutex) : impl_(new Monitor::Impl(mutex)) {
|
||||
}
|
||||
Monitor::Monitor(Monitor* monitor) : impl_(new Monitor::Impl(monitor)) {
|
||||
}
|
||||
|
||||
Monitor::~Monitor() {
|
||||
delete impl_;
|
||||
}
|
||||
|
||||
Mutex& Monitor::mutex() const {
|
||||
return const_cast<Monitor::Impl*>(impl_)->mutex();
|
||||
}
|
||||
|
||||
void Monitor::lock() const {
|
||||
const_cast<Monitor::Impl*>(impl_)->lock();
|
||||
}
|
||||
|
||||
void Monitor::unlock() const {
|
||||
const_cast<Monitor::Impl*>(impl_)->unlock();
|
||||
}
|
||||
|
||||
void Monitor::wait(int64_t timeout) const {
|
||||
const_cast<Monitor::Impl*>(impl_)->wait(timeout);
|
||||
}
|
||||
|
||||
int Monitor::waitForTime(const THRIFT_TIMESPEC* abstime) const {
|
||||
return const_cast<Monitor::Impl*>(impl_)->waitForTime(abstime);
|
||||
}
|
||||
|
||||
int Monitor::waitForTime(const timeval* abstime) const {
|
||||
return const_cast<Monitor::Impl*>(impl_)->waitForTime(abstime);
|
||||
}
|
||||
|
||||
int Monitor::waitForTimeRelative(int64_t timeout_ms) const {
|
||||
return const_cast<Monitor::Impl*>(impl_)->waitForTimeRelative(timeout_ms);
|
||||
}
|
||||
|
||||
int Monitor::waitForever() const {
|
||||
return const_cast<Monitor::Impl*>(impl_)->waitForever();
|
||||
}
|
||||
|
||||
void Monitor::notify() const {
|
||||
const_cast<Monitor::Impl*>(impl_)->notify();
|
||||
}
|
||||
|
||||
void Monitor::notifyAll() const {
|
||||
const_cast<Monitor::Impl*>(impl_)->notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
67
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/StdMutex.cpp
generated
vendored
Normal file
67
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/StdMutex.cpp
generated
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/thrift-config.h>
|
||||
|
||||
#include <thrift/concurrency/Mutex.h>
|
||||
#include <thrift/concurrency/Util.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
/**
|
||||
* Implementation of Mutex class using C++11 std::timed_mutex
|
||||
*
|
||||
* @version $Id:$
|
||||
*/
|
||||
class Mutex::impl : public std::timed_mutex {};
|
||||
|
||||
Mutex::Mutex(Initializer init) : impl_(new Mutex::impl()) {
|
||||
}
|
||||
|
||||
void* Mutex::getUnderlyingImpl() const {
|
||||
return impl_.get();
|
||||
}
|
||||
|
||||
void Mutex::lock() const {
|
||||
impl_->lock();
|
||||
}
|
||||
|
||||
bool Mutex::trylock() const {
|
||||
return impl_->try_lock();
|
||||
}
|
||||
|
||||
bool Mutex::timedlock(int64_t ms) const {
|
||||
return impl_->try_lock_for(std::chrono::milliseconds(ms));
|
||||
}
|
||||
|
||||
void Mutex::unlock() const {
|
||||
impl_->unlock();
|
||||
}
|
||||
|
||||
void Mutex::DEFAULT_INITIALIZER(void* arg) {
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
135
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/StdThreadFactory.cpp
generated
vendored
Normal file
135
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/StdThreadFactory.cpp
generated
vendored
Normal file
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/thrift-config.h>
|
||||
|
||||
#if USE_STD_THREAD
|
||||
|
||||
#include <thrift/concurrency/StdThreadFactory.h>
|
||||
#include <thrift/concurrency/Exception.h>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <thread>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
/**
|
||||
* The C++11 thread class.
|
||||
*
|
||||
* Note that we use boost shared_ptr rather than std shared_ptrs here
|
||||
* because the Thread/Runnable classes use those and we don't want to
|
||||
* mix them.
|
||||
*
|
||||
* @version $Id:$
|
||||
*/
|
||||
class StdThread : public Thread, public boost::enable_shared_from_this<StdThread> {
|
||||
public:
|
||||
enum STATE { uninitialized, starting, started, stopping, stopped };
|
||||
|
||||
static void threadMain(boost::shared_ptr<StdThread> thread);
|
||||
|
||||
private:
|
||||
std::unique_ptr<std::thread> thread_;
|
||||
STATE state_;
|
||||
bool detached_;
|
||||
|
||||
public:
|
||||
StdThread(bool detached, boost::shared_ptr<Runnable> runnable)
|
||||
: state_(uninitialized), detached_(detached) {
|
||||
this->Thread::runnable(runnable);
|
||||
}
|
||||
|
||||
~StdThread() {
|
||||
if (!detached_) {
|
||||
try {
|
||||
join();
|
||||
} catch (...) {
|
||||
// We're really hosed.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void start() {
|
||||
if (state_ != uninitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<StdThread> selfRef = shared_from_this();
|
||||
state_ = starting;
|
||||
|
||||
thread_ = std::unique_ptr<std::thread>(new std::thread(threadMain, selfRef));
|
||||
|
||||
if (detached_)
|
||||
thread_->detach();
|
||||
}
|
||||
|
||||
void join() {
|
||||
if (!detached_ && state_ != uninitialized) {
|
||||
thread_->join();
|
||||
}
|
||||
}
|
||||
|
||||
Thread::id_t getId() { return thread_.get() ? thread_->get_id() : std::thread::id(); }
|
||||
|
||||
boost::shared_ptr<Runnable> runnable() const { return Thread::runnable(); }
|
||||
|
||||
void runnable(boost::shared_ptr<Runnable> value) { Thread::runnable(value); }
|
||||
};
|
||||
|
||||
void StdThread::threadMain(boost::shared_ptr<StdThread> thread) {
|
||||
if (thread == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (thread->state_ != starting) {
|
||||
return;
|
||||
}
|
||||
|
||||
thread->state_ = started;
|
||||
thread->runnable()->run();
|
||||
|
||||
if (thread->state_ != stopping && thread->state_ != stopped) {
|
||||
thread->state_ = stopping;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
StdThreadFactory::StdThreadFactory(bool detached) : ThreadFactory(detached) {
|
||||
}
|
||||
|
||||
boost::shared_ptr<Thread> StdThreadFactory::newThread(boost::shared_ptr<Runnable> runnable) const {
|
||||
boost::shared_ptr<StdThread> result = boost::shared_ptr<StdThread>(new StdThread(isDetached(), runnable));
|
||||
runnable->thread(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
Thread::id_t StdThreadFactory::getCurrentThreadId() const {
|
||||
return std::this_thread::get_id();
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
||||
|
||||
#endif // USE_STD_THREAD
|
61
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/StdThreadFactory.h
generated
vendored
Normal file
61
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/StdThreadFactory.h
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_CONCURRENCY_STDTHREADFACTORY_H_
|
||||
#define _THRIFT_CONCURRENCY_STDTHREADFACTORY_H_ 1
|
||||
|
||||
#include <thrift/concurrency/Thread.h>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
/**
|
||||
* A thread factory to create std::threads.
|
||||
*
|
||||
* @version $Id:$
|
||||
*/
|
||||
class StdThreadFactory : public ThreadFactory {
|
||||
|
||||
public:
|
||||
/**
|
||||
* Std thread factory. All threads created by a factory are reference-counted
|
||||
* via boost::shared_ptr and boost::weak_ptr. The factory guarantees that threads and
|
||||
* the Runnable tasks they host will be properly cleaned up once the last strong reference
|
||||
* to both is given up.
|
||||
*
|
||||
* By default threads are not joinable.
|
||||
*/
|
||||
|
||||
StdThreadFactory(bool detached = true);
|
||||
|
||||
// From ThreadFactory;
|
||||
boost::shared_ptr<Thread> newThread(boost::shared_ptr<Runnable> runnable) const;
|
||||
|
||||
// From ThreadFactory;
|
||||
Thread::id_t getCurrentThreadId() const;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
||||
|
||||
#endif // #ifndef _THRIFT_CONCURRENCY_STDTHREADFACTORY_H_
|
178
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/Thread.h
generated
vendored
Normal file
178
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/Thread.h
generated
vendored
Normal file
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_CONCURRENCY_THREAD_H_
|
||||
#define _THRIFT_CONCURRENCY_THREAD_H_ 1
|
||||
|
||||
#include <stdint.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
|
||||
#include <thrift/thrift-config.h>
|
||||
|
||||
#if USE_BOOST_THREAD
|
||||
#include <boost/thread.hpp>
|
||||
#elif USE_STD_THREAD
|
||||
#include <thread>
|
||||
#else
|
||||
#ifdef HAVE_PTHREAD_H
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
class Thread;
|
||||
|
||||
/**
|
||||
* Minimal runnable class. More or less analogous to java.lang.Runnable.
|
||||
*
|
||||
* @version $Id:$
|
||||
*/
|
||||
class Runnable {
|
||||
|
||||
public:
|
||||
virtual ~Runnable(){};
|
||||
virtual void run() = 0;
|
||||
|
||||
/**
|
||||
* Gets the thread object that is hosting this runnable object - can return
|
||||
* an empty boost::shared pointer if no references remain on that thread object
|
||||
*/
|
||||
virtual boost::shared_ptr<Thread> thread() { return thread_.lock(); }
|
||||
|
||||
/**
|
||||
* Sets the thread that is executing this object. This is only meant for
|
||||
* use by concrete implementations of Thread.
|
||||
*/
|
||||
virtual void thread(boost::shared_ptr<Thread> value) { thread_ = value; }
|
||||
|
||||
private:
|
||||
boost::weak_ptr<Thread> thread_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Minimal thread class. Returned by thread factory bound to a Runnable object
|
||||
* and ready to start execution. More or less analogous to java.lang.Thread
|
||||
* (minus all the thread group, priority, mode and other baggage, since that
|
||||
* is difficult to abstract across platforms and is left for platform-specific
|
||||
* ThreadFactory implemtations to deal with
|
||||
*
|
||||
* @see apache::thrift::concurrency::ThreadFactory)
|
||||
*/
|
||||
class Thread {
|
||||
|
||||
public:
|
||||
#if USE_BOOST_THREAD
|
||||
typedef boost::thread::id id_t;
|
||||
|
||||
static inline bool is_current(id_t t) { return t == boost::this_thread::get_id(); }
|
||||
static inline id_t get_current() { return boost::this_thread::get_id(); }
|
||||
#elif USE_STD_THREAD
|
||||
typedef std::thread::id id_t;
|
||||
|
||||
static inline bool is_current(id_t t) { return t == std::this_thread::get_id(); }
|
||||
static inline id_t get_current() { return std::this_thread::get_id(); }
|
||||
#else
|
||||
typedef pthread_t id_t;
|
||||
|
||||
static inline bool is_current(id_t t) { return pthread_equal(pthread_self(), t); }
|
||||
static inline id_t get_current() { return pthread_self(); }
|
||||
#endif
|
||||
|
||||
virtual ~Thread(){};
|
||||
|
||||
/**
|
||||
* Starts the thread. Does platform specific thread creation and
|
||||
* configuration then invokes the run method of the Runnable object bound
|
||||
* to this thread.
|
||||
*/
|
||||
virtual void start() = 0;
|
||||
|
||||
/**
|
||||
* Join this thread. If this thread is joinable, the calling thread blocks
|
||||
* until this thread completes. If the target thread is not joinable, then
|
||||
* nothing happens.
|
||||
*/
|
||||
virtual void join() = 0;
|
||||
|
||||
/**
|
||||
* Gets the thread's platform-specific ID
|
||||
*/
|
||||
virtual id_t getId() = 0;
|
||||
|
||||
/**
|
||||
* Gets the runnable object this thread is hosting
|
||||
*/
|
||||
virtual boost::shared_ptr<Runnable> runnable() const { return _runnable; }
|
||||
|
||||
protected:
|
||||
virtual void runnable(boost::shared_ptr<Runnable> value) { _runnable = value; }
|
||||
|
||||
private:
|
||||
boost::shared_ptr<Runnable> _runnable;
|
||||
};
|
||||
|
||||
/**
|
||||
* Factory to create platform-specific thread object and bind them to Runnable
|
||||
* object for execution
|
||||
*/
|
||||
class ThreadFactory {
|
||||
protected:
|
||||
ThreadFactory(bool detached) : detached_(detached) { }
|
||||
|
||||
public:
|
||||
virtual ~ThreadFactory() { }
|
||||
|
||||
/**
|
||||
* Gets current detached mode
|
||||
*/
|
||||
bool isDetached() const { return detached_; }
|
||||
|
||||
/**
|
||||
* Sets the detached disposition of newly created threads.
|
||||
*/
|
||||
void setDetached(bool detached) { detached_ = detached; }
|
||||
|
||||
/**
|
||||
* Create a new thread.
|
||||
*/
|
||||
virtual boost::shared_ptr<Thread> newThread(boost::shared_ptr<Runnable> runnable) const = 0;
|
||||
|
||||
/**
|
||||
* Gets the current thread id or unknown_thread_id if the current thread is not a thrift thread
|
||||
*/
|
||||
virtual Thread::id_t getCurrentThreadId() const = 0;
|
||||
|
||||
/**
|
||||
* For code readability define the unknown/undefined thread id
|
||||
*/
|
||||
static const Thread::id_t unknown_thread_id;
|
||||
|
||||
private:
|
||||
bool detached_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
||||
|
||||
#endif // #ifndef _THRIFT_CONCURRENCY_THREAD_H_
|
588
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/ThreadManager.cpp
generated
vendored
Normal file
588
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/ThreadManager.cpp
generated
vendored
Normal file
|
@ -0,0 +1,588 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/thrift-config.h>
|
||||
|
||||
#include <thrift/concurrency/ThreadManager.h>
|
||||
#include <thrift/concurrency/Exception.h>
|
||||
#include <thrift/concurrency/Monitor.h>
|
||||
#include <thrift/concurrency/Util.h>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <deque>
|
||||
#include <set>
|
||||
|
||||
#if defined(DEBUG)
|
||||
#include <iostream>
|
||||
#endif // defined(DEBUG)
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
using boost::shared_ptr;
|
||||
using boost::dynamic_pointer_cast;
|
||||
|
||||
/**
|
||||
* ThreadManager class
|
||||
*
|
||||
* This class manages a pool of threads. It uses a ThreadFactory to create
|
||||
* threads. It never actually creates or destroys worker threads, rather
|
||||
* it maintains statistics on number of idle threads, number of active threads,
|
||||
* task backlog, and average wait and service times.
|
||||
*
|
||||
* There are three different monitors used for signaling different conditions
|
||||
* however they all share the same mutex_.
|
||||
*
|
||||
* @version $Id:$
|
||||
*/
|
||||
class ThreadManager::Impl : public ThreadManager {
|
||||
|
||||
public:
|
||||
Impl()
|
||||
: workerCount_(0),
|
||||
workerMaxCount_(0),
|
||||
idleCount_(0),
|
||||
pendingTaskCountMax_(0),
|
||||
expiredCount_(0),
|
||||
state_(ThreadManager::UNINITIALIZED),
|
||||
monitor_(&mutex_),
|
||||
maxMonitor_(&mutex_),
|
||||
workerMonitor_(&mutex_) {}
|
||||
|
||||
~Impl() { stop(); }
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
ThreadManager::STATE state() const { return state_; }
|
||||
|
||||
shared_ptr<ThreadFactory> threadFactory() const {
|
||||
Guard g(mutex_);
|
||||
return threadFactory_;
|
||||
}
|
||||
|
||||
void threadFactory(shared_ptr<ThreadFactory> value) {
|
||||
Guard g(mutex_);
|
||||
if (threadFactory_ && threadFactory_->isDetached() != value->isDetached()) {
|
||||
throw InvalidArgumentException();
|
||||
}
|
||||
threadFactory_ = value;
|
||||
}
|
||||
|
||||
void addWorker(size_t value);
|
||||
|
||||
void removeWorker(size_t value);
|
||||
|
||||
size_t idleWorkerCount() const { return idleCount_; }
|
||||
|
||||
size_t workerCount() const {
|
||||
Guard g(mutex_);
|
||||
return workerCount_;
|
||||
}
|
||||
|
||||
size_t pendingTaskCount() const {
|
||||
Guard g(mutex_);
|
||||
return tasks_.size();
|
||||
}
|
||||
|
||||
size_t totalTaskCount() const {
|
||||
Guard g(mutex_);
|
||||
return tasks_.size() + workerCount_ - idleCount_;
|
||||
}
|
||||
|
||||
size_t pendingTaskCountMax() const {
|
||||
Guard g(mutex_);
|
||||
return pendingTaskCountMax_;
|
||||
}
|
||||
|
||||
size_t expiredTaskCount() {
|
||||
Guard g(mutex_);
|
||||
return expiredCount_;
|
||||
}
|
||||
|
||||
void pendingTaskCountMax(const size_t value) {
|
||||
Guard g(mutex_);
|
||||
pendingTaskCountMax_ = value;
|
||||
}
|
||||
|
||||
void add(shared_ptr<Runnable> value, int64_t timeout, int64_t expiration);
|
||||
|
||||
void remove(shared_ptr<Runnable> task);
|
||||
|
||||
shared_ptr<Runnable> removeNextPending();
|
||||
|
||||
void removeExpiredTasks() {
|
||||
removeExpired(false);
|
||||
}
|
||||
|
||||
void setExpireCallback(ExpireCallback expireCallback);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Remove one or more expired tasks.
|
||||
* \param[in] justOne if true, try to remove just one task and return
|
||||
*/
|
||||
void removeExpired(bool justOne);
|
||||
|
||||
/**
|
||||
* \returns whether it is acceptable to block, depending on the current thread id
|
||||
*/
|
||||
bool canSleep() const;
|
||||
|
||||
/**
|
||||
* Lowers the maximum worker count and blocks until enough worker threads complete
|
||||
* to get to the new maximum worker limit. The caller is responsible for acquiring
|
||||
* a lock on the class mutex_.
|
||||
*/
|
||||
void removeWorkersUnderLock(size_t value);
|
||||
|
||||
size_t workerCount_;
|
||||
size_t workerMaxCount_;
|
||||
size_t idleCount_;
|
||||
size_t pendingTaskCountMax_;
|
||||
size_t expiredCount_;
|
||||
ExpireCallback expireCallback_;
|
||||
|
||||
ThreadManager::STATE state_;
|
||||
shared_ptr<ThreadFactory> threadFactory_;
|
||||
|
||||
friend class ThreadManager::Task;
|
||||
typedef std::deque<shared_ptr<Task> > TaskQueue;
|
||||
TaskQueue tasks_;
|
||||
Mutex mutex_;
|
||||
Monitor monitor_;
|
||||
Monitor maxMonitor_;
|
||||
Monitor workerMonitor_; // used to synchronize changes in worker count
|
||||
|
||||
friend class ThreadManager::Worker;
|
||||
std::set<shared_ptr<Thread> > workers_;
|
||||
std::set<shared_ptr<Thread> > deadWorkers_;
|
||||
std::map<const Thread::id_t, shared_ptr<Thread> > idMap_;
|
||||
};
|
||||
|
||||
class ThreadManager::Task : public Runnable {
|
||||
|
||||
public:
|
||||
enum STATE { WAITING, EXECUTING, TIMEDOUT, COMPLETE };
|
||||
|
||||
Task(shared_ptr<Runnable> runnable, int64_t expiration = 0LL)
|
||||
: runnable_(runnable),
|
||||
state_(WAITING),
|
||||
expireTime_(expiration != 0LL ? Util::currentTime() + expiration : 0LL) {}
|
||||
|
||||
~Task() {}
|
||||
|
||||
void run() {
|
||||
if (state_ == EXECUTING) {
|
||||
runnable_->run();
|
||||
state_ = COMPLETE;
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<Runnable> getRunnable() { return runnable_; }
|
||||
|
||||
int64_t getExpireTime() const { return expireTime_; }
|
||||
|
||||
private:
|
||||
shared_ptr<Runnable> runnable_;
|
||||
friend class ThreadManager::Worker;
|
||||
STATE state_;
|
||||
int64_t expireTime_;
|
||||
};
|
||||
|
||||
class ThreadManager::Worker : public Runnable {
|
||||
enum STATE { UNINITIALIZED, STARTING, STARTED, STOPPING, STOPPED };
|
||||
|
||||
public:
|
||||
Worker(ThreadManager::Impl* manager) : manager_(manager), state_(UNINITIALIZED) {}
|
||||
|
||||
~Worker() {}
|
||||
|
||||
private:
|
||||
bool isActive() const {
|
||||
return (manager_->workerCount_ <= manager_->workerMaxCount_)
|
||||
|| (manager_->state_ == JOINING && !manager_->tasks_.empty());
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* Worker entry point
|
||||
*
|
||||
* As long as worker thread is running, pull tasks off the task queue and
|
||||
* execute.
|
||||
*/
|
||||
void run() {
|
||||
Guard g(manager_->mutex_);
|
||||
|
||||
/**
|
||||
* This method has three parts; one is to check for and account for
|
||||
* admitting a task which happens under a lock. Then the lock is released
|
||||
* and the task itself is executed. Finally we do some accounting
|
||||
* under lock again when the task completes.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Admitting
|
||||
*/
|
||||
|
||||
/**
|
||||
* Increment worker semaphore and notify manager if worker count reached
|
||||
* desired max
|
||||
*/
|
||||
bool active = manager_->workerCount_ < manager_->workerMaxCount_;
|
||||
if (active) {
|
||||
if (++manager_->workerCount_ == manager_->workerMaxCount_) {
|
||||
manager_->workerMonitor_.notify();
|
||||
}
|
||||
}
|
||||
|
||||
while (active) {
|
||||
/**
|
||||
* While holding manager monitor block for non-empty task queue (Also
|
||||
* check that the thread hasn't been requested to stop). Once the queue
|
||||
* is non-empty, dequeue a task, release monitor, and execute. If the
|
||||
* worker max count has been decremented such that we exceed it, mark
|
||||
* ourself inactive, decrement the worker count and notify the manager
|
||||
* (technically we're notifying the next blocked thread but eventually
|
||||
* the manager will see it.
|
||||
*/
|
||||
active = isActive();
|
||||
|
||||
while (active && manager_->tasks_.empty()) {
|
||||
manager_->idleCount_++;
|
||||
manager_->monitor_.wait();
|
||||
active = isActive();
|
||||
manager_->idleCount_--;
|
||||
}
|
||||
|
||||
shared_ptr<ThreadManager::Task> task;
|
||||
|
||||
if (active) {
|
||||
if (!manager_->tasks_.empty()) {
|
||||
task = manager_->tasks_.front();
|
||||
manager_->tasks_.pop_front();
|
||||
if (task->state_ == ThreadManager::Task::WAITING) {
|
||||
// If the state is changed to anything other than EXECUTING or TIMEDOUT here
|
||||
// then the execution loop needs to be changed below.
|
||||
task->state_ =
|
||||
(task->getExpireTime() && task->getExpireTime() < Util::currentTime()) ?
|
||||
ThreadManager::Task::TIMEDOUT :
|
||||
ThreadManager::Task::EXECUTING;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we have a pending task max and we just dropped below it, wakeup any
|
||||
thread that might be blocked on add. */
|
||||
if (manager_->pendingTaskCountMax_ != 0
|
||||
&& manager_->tasks_.size() <= manager_->pendingTaskCountMax_ - 1) {
|
||||
manager_->maxMonitor_.notify();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execution - not holding a lock
|
||||
*/
|
||||
if (task) {
|
||||
if (task->state_ == ThreadManager::Task::EXECUTING) {
|
||||
|
||||
// Release the lock so we can run the task without blocking the thread manager
|
||||
manager_->mutex_.unlock();
|
||||
|
||||
try {
|
||||
task->run();
|
||||
} catch (const std::exception& e) {
|
||||
GlobalOutput.printf("[ERROR] task->run() raised an exception: %s", e.what());
|
||||
} catch (...) {
|
||||
GlobalOutput.printf("[ERROR] task->run() raised an unknown exception");
|
||||
}
|
||||
|
||||
// Re-acquire the lock to proceed in the thread manager
|
||||
manager_->mutex_.lock();
|
||||
|
||||
} else if (manager_->expireCallback_) {
|
||||
// The only other state the task could have been in is TIMEDOUT (see above)
|
||||
manager_->expireCallback_(task->getRunnable());
|
||||
manager_->expiredCount_++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Final accounting for the worker thread that is done working
|
||||
*/
|
||||
manager_->deadWorkers_.insert(this->thread());
|
||||
if (--manager_->workerCount_ == manager_->workerMaxCount_) {
|
||||
manager_->workerMonitor_.notify();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ThreadManager::Impl* manager_;
|
||||
friend class ThreadManager::Impl;
|
||||
STATE state_;
|
||||
};
|
||||
|
||||
void ThreadManager::Impl::addWorker(size_t value) {
|
||||
std::set<shared_ptr<Thread> > newThreads;
|
||||
for (size_t ix = 0; ix < value; ix++) {
|
||||
shared_ptr<ThreadManager::Worker> worker
|
||||
= shared_ptr<ThreadManager::Worker>(new ThreadManager::Worker(this));
|
||||
newThreads.insert(threadFactory_->newThread(worker));
|
||||
}
|
||||
|
||||
Guard g(mutex_);
|
||||
workerMaxCount_ += value;
|
||||
workers_.insert(newThreads.begin(), newThreads.end());
|
||||
|
||||
for (std::set<shared_ptr<Thread> >::iterator ix = newThreads.begin(); ix != newThreads.end();
|
||||
++ix) {
|
||||
shared_ptr<ThreadManager::Worker> worker
|
||||
= dynamic_pointer_cast<ThreadManager::Worker, Runnable>((*ix)->runnable());
|
||||
worker->state_ = ThreadManager::Worker::STARTING;
|
||||
(*ix)->start();
|
||||
idMap_.insert(std::pair<const Thread::id_t, shared_ptr<Thread> >((*ix)->getId(), *ix));
|
||||
}
|
||||
|
||||
while (workerCount_ != workerMaxCount_) {
|
||||
workerMonitor_.wait();
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadManager::Impl::start() {
|
||||
Guard g(mutex_);
|
||||
if (state_ == ThreadManager::STOPPED) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state_ == ThreadManager::UNINITIALIZED) {
|
||||
if (!threadFactory_) {
|
||||
throw InvalidArgumentException();
|
||||
}
|
||||
state_ = ThreadManager::STARTED;
|
||||
monitor_.notifyAll();
|
||||
}
|
||||
|
||||
while (state_ == STARTING) {
|
||||
monitor_.wait();
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadManager::Impl::stop() {
|
||||
Guard g(mutex_);
|
||||
bool doStop = false;
|
||||
|
||||
if (state_ != ThreadManager::STOPPING && state_ != ThreadManager::JOINING
|
||||
&& state_ != ThreadManager::STOPPED) {
|
||||
doStop = true;
|
||||
state_ = ThreadManager::JOINING;
|
||||
}
|
||||
|
||||
if (doStop) {
|
||||
removeWorkersUnderLock(workerCount_);
|
||||
}
|
||||
|
||||
state_ = ThreadManager::STOPPED;
|
||||
}
|
||||
|
||||
void ThreadManager::Impl::removeWorker(size_t value) {
|
||||
Guard g(mutex_);
|
||||
removeWorkersUnderLock(value);
|
||||
}
|
||||
|
||||
void ThreadManager::Impl::removeWorkersUnderLock(size_t value) {
|
||||
if (value > workerMaxCount_) {
|
||||
throw InvalidArgumentException();
|
||||
}
|
||||
|
||||
workerMaxCount_ -= value;
|
||||
|
||||
if (idleCount_ > value) {
|
||||
// There are more idle workers than we need to remove,
|
||||
// so notify enough of them so they can terminate.
|
||||
for (size_t ix = 0; ix < value; ix++) {
|
||||
monitor_.notify();
|
||||
}
|
||||
} else {
|
||||
// There are as many or less idle workers than we need to remove,
|
||||
// so just notify them all so they can terminate.
|
||||
monitor_.notifyAll();
|
||||
}
|
||||
|
||||
while (workerCount_ != workerMaxCount_) {
|
||||
workerMonitor_.wait();
|
||||
}
|
||||
|
||||
for (std::set<shared_ptr<Thread> >::iterator ix = deadWorkers_.begin();
|
||||
ix != deadWorkers_.end();
|
||||
++ix) {
|
||||
|
||||
// when used with a joinable thread factory, we join the threads as we remove them
|
||||
if (!threadFactory_->isDetached()) {
|
||||
(*ix)->join();
|
||||
}
|
||||
|
||||
idMap_.erase((*ix)->getId());
|
||||
workers_.erase(*ix);
|
||||
}
|
||||
|
||||
deadWorkers_.clear();
|
||||
}
|
||||
|
||||
bool ThreadManager::Impl::canSleep() const {
|
||||
const Thread::id_t id = threadFactory_->getCurrentThreadId();
|
||||
return idMap_.find(id) == idMap_.end();
|
||||
}
|
||||
|
||||
void ThreadManager::Impl::add(shared_ptr<Runnable> value, int64_t timeout, int64_t expiration) {
|
||||
Guard g(mutex_, timeout);
|
||||
|
||||
if (!g) {
|
||||
throw TimedOutException();
|
||||
}
|
||||
|
||||
if (state_ != ThreadManager::STARTED) {
|
||||
throw IllegalStateException(
|
||||
"ThreadManager::Impl::add ThreadManager "
|
||||
"not started");
|
||||
}
|
||||
|
||||
// if we're at a limit, remove an expired task to see if the limit clears
|
||||
if (pendingTaskCountMax_ > 0 && (tasks_.size() >= pendingTaskCountMax_)) {
|
||||
removeExpired(true);
|
||||
}
|
||||
|
||||
if (pendingTaskCountMax_ > 0 && (tasks_.size() >= pendingTaskCountMax_)) {
|
||||
if (canSleep() && timeout >= 0) {
|
||||
while (pendingTaskCountMax_ > 0 && tasks_.size() >= pendingTaskCountMax_) {
|
||||
// This is thread safe because the mutex is shared between monitors.
|
||||
maxMonitor_.wait(timeout);
|
||||
}
|
||||
} else {
|
||||
throw TooManyPendingTasksException();
|
||||
}
|
||||
}
|
||||
|
||||
tasks_.push_back(shared_ptr<ThreadManager::Task>(new ThreadManager::Task(value, expiration)));
|
||||
|
||||
// If idle thread is available notify it, otherwise all worker threads are
|
||||
// running and will get around to this task in time.
|
||||
if (idleCount_ > 0) {
|
||||
monitor_.notify();
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadManager::Impl::remove(shared_ptr<Runnable> task) {
|
||||
Guard g(mutex_);
|
||||
if (state_ != ThreadManager::STARTED) {
|
||||
throw IllegalStateException(
|
||||
"ThreadManager::Impl::remove ThreadManager not "
|
||||
"started");
|
||||
}
|
||||
|
||||
for (TaskQueue::iterator it = tasks_.begin(); it != tasks_.end(); ++it)
|
||||
{
|
||||
if ((*it)->getRunnable() == task)
|
||||
{
|
||||
tasks_.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<Runnable> ThreadManager::Impl::removeNextPending() {
|
||||
Guard g(mutex_);
|
||||
if (state_ != ThreadManager::STARTED) {
|
||||
throw IllegalStateException(
|
||||
"ThreadManager::Impl::removeNextPending "
|
||||
"ThreadManager not started");
|
||||
}
|
||||
|
||||
if (tasks_.empty()) {
|
||||
return boost::shared_ptr<Runnable>();
|
||||
}
|
||||
|
||||
shared_ptr<ThreadManager::Task> task = tasks_.front();
|
||||
tasks_.pop_front();
|
||||
|
||||
return task->getRunnable();
|
||||
}
|
||||
|
||||
void ThreadManager::Impl::removeExpired(bool justOne) {
|
||||
// this is always called under a lock
|
||||
int64_t now = 0LL;
|
||||
|
||||
for (TaskQueue::iterator it = tasks_.begin(); it != tasks_.end(); )
|
||||
{
|
||||
if (now == 0LL) {
|
||||
now = Util::currentTime();
|
||||
}
|
||||
|
||||
if ((*it)->getExpireTime() > 0LL && (*it)->getExpireTime() < now) {
|
||||
if (expireCallback_) {
|
||||
expireCallback_((*it)->getRunnable());
|
||||
}
|
||||
it = tasks_.erase(it);
|
||||
++expiredCount_;
|
||||
if (justOne) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadManager::Impl::setExpireCallback(ExpireCallback expireCallback) {
|
||||
Guard g(mutex_);
|
||||
expireCallback_ = expireCallback;
|
||||
}
|
||||
|
||||
class SimpleThreadManager : public ThreadManager::Impl {
|
||||
|
||||
public:
|
||||
SimpleThreadManager(size_t workerCount = 4, size_t pendingTaskCountMax = 0)
|
||||
: workerCount_(workerCount), pendingTaskCountMax_(pendingTaskCountMax) {}
|
||||
|
||||
void start() {
|
||||
ThreadManager::Impl::pendingTaskCountMax(pendingTaskCountMax_);
|
||||
ThreadManager::Impl::start();
|
||||
addWorker(workerCount_);
|
||||
}
|
||||
|
||||
private:
|
||||
const size_t workerCount_;
|
||||
const size_t pendingTaskCountMax_;
|
||||
};
|
||||
|
||||
shared_ptr<ThreadManager> ThreadManager::newThreadManager() {
|
||||
return shared_ptr<ThreadManager>(new ThreadManager::Impl());
|
||||
}
|
||||
|
||||
shared_ptr<ThreadManager> ThreadManager::newSimpleThreadManager(size_t count,
|
||||
size_t pendingTaskCountMax) {
|
||||
return shared_ptr<ThreadManager>(new SimpleThreadManager(count, pendingTaskCountMax));
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
214
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/ThreadManager.h
generated
vendored
Normal file
214
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/ThreadManager.h
generated
vendored
Normal file
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_CONCURRENCY_THREADMANAGER_H_
|
||||
#define _THRIFT_CONCURRENCY_THREADMANAGER_H_ 1
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <thrift/cxxfunctional.h>
|
||||
#include <sys/types.h>
|
||||
#include <thrift/concurrency/Thread.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
/**
|
||||
* Thread Pool Manager and related classes
|
||||
*
|
||||
* @version $Id:$
|
||||
*/
|
||||
class ThreadManager;
|
||||
|
||||
/**
|
||||
* ThreadManager class
|
||||
*
|
||||
* This class manages a pool of threads. It uses a ThreadFactory to create
|
||||
* threads. It never actually creates or destroys worker threads, rather
|
||||
* it maintains statistics on number of idle threads, number of active threads,
|
||||
* task backlog, and average wait and service times and informs the PoolPolicy
|
||||
* object bound to instances of this manager of interesting transitions. It is
|
||||
* then up the PoolPolicy object to decide if the thread pool size needs to be
|
||||
* adjusted and call this object addWorker and removeWorker methods to make
|
||||
* changes.
|
||||
*
|
||||
* This design allows different policy implementations to use this code to
|
||||
* handle basic worker thread management and worker task execution and focus on
|
||||
* policy issues. The simplest policy, StaticPolicy, does nothing other than
|
||||
* create a fixed number of threads.
|
||||
*/
|
||||
class ThreadManager {
|
||||
|
||||
protected:
|
||||
ThreadManager() {}
|
||||
|
||||
public:
|
||||
typedef apache::thrift::stdcxx::function<void(boost::shared_ptr<Runnable>)> ExpireCallback;
|
||||
|
||||
virtual ~ThreadManager() {}
|
||||
|
||||
/**
|
||||
* Starts the thread manager. Verifies all attributes have been properly
|
||||
* initialized, then allocates necessary resources to begin operation
|
||||
*/
|
||||
virtual void start() = 0;
|
||||
|
||||
/**
|
||||
* Stops the thread manager. Aborts all remaining unprocessed task, shuts
|
||||
* down all created worker threads, and releases all allocated resources.
|
||||
* This method blocks for all worker threads to complete, thus it can
|
||||
* potentially block forever if a worker thread is running a task that
|
||||
* won't terminate.
|
||||
*
|
||||
* Worker threads will be joined depending on the threadFactory's detached
|
||||
* disposition.
|
||||
*/
|
||||
virtual void stop() = 0;
|
||||
|
||||
enum STATE { UNINITIALIZED, STARTING, STARTED, JOINING, STOPPING, STOPPED };
|
||||
|
||||
virtual STATE state() const = 0;
|
||||
|
||||
/**
|
||||
* \returns the current thread factory
|
||||
*/
|
||||
virtual boost::shared_ptr<ThreadFactory> threadFactory() const = 0;
|
||||
|
||||
/**
|
||||
* Set the thread factory.
|
||||
* \throws InvalidArgumentException if the new thread factory has a different
|
||||
* detached disposition than the one replacing it
|
||||
*/
|
||||
virtual void threadFactory(boost::shared_ptr<ThreadFactory> value) = 0;
|
||||
|
||||
/**
|
||||
* Adds worker thread(s).
|
||||
*/
|
||||
virtual void addWorker(size_t value = 1) = 0;
|
||||
|
||||
/**
|
||||
* Removes worker thread(s).
|
||||
* Threads are joined if the thread factory detached disposition allows it.
|
||||
* Blocks until the number of worker threads reaches the new limit.
|
||||
* \param[in] value the number to remove
|
||||
* \throws InvalidArgumentException if the value is greater than the number
|
||||
* of workers
|
||||
*/
|
||||
virtual void removeWorker(size_t value = 1) = 0;
|
||||
|
||||
/**
|
||||
* Gets the current number of idle worker threads
|
||||
*/
|
||||
virtual size_t idleWorkerCount() const = 0;
|
||||
|
||||
/**
|
||||
* Gets the current number of total worker threads
|
||||
*/
|
||||
virtual size_t workerCount() const = 0;
|
||||
|
||||
/**
|
||||
* Gets the current number of pending tasks
|
||||
*/
|
||||
virtual size_t pendingTaskCount() const = 0;
|
||||
|
||||
/**
|
||||
* Gets the current number of pending and executing tasks
|
||||
*/
|
||||
virtual size_t totalTaskCount() const = 0;
|
||||
|
||||
/**
|
||||
* Gets the maximum pending task count. 0 indicates no maximum
|
||||
*/
|
||||
virtual size_t pendingTaskCountMax() const = 0;
|
||||
|
||||
/**
|
||||
* Gets the number of tasks which have been expired without being run
|
||||
* since start() was called.
|
||||
*/
|
||||
virtual size_t expiredTaskCount() = 0;
|
||||
|
||||
/**
|
||||
* Adds a task to be executed at some time in the future by a worker thread.
|
||||
*
|
||||
* This method will block if pendingTaskCountMax() in not zero and pendingTaskCount()
|
||||
* is greater than or equalt to pendingTaskCountMax(). If this method is called in the
|
||||
* context of a ThreadManager worker thread it will throw a
|
||||
* TooManyPendingTasksException
|
||||
*
|
||||
* @param task The task to queue for execution
|
||||
*
|
||||
* @param timeout Time to wait in milliseconds to add a task when a pending-task-count
|
||||
* is specified. Specific cases:
|
||||
* timeout = 0 : Wait forever to queue task.
|
||||
* timeout = -1 : Return immediately if pending task count exceeds specified max
|
||||
* @param expiration when nonzero, the number of milliseconds the task is valid
|
||||
* to be run; if exceeded, the task will be dropped off the queue and not run.
|
||||
*
|
||||
* @throws TooManyPendingTasksException Pending task count exceeds max pending task count
|
||||
*/
|
||||
virtual void add(boost::shared_ptr<Runnable> task,
|
||||
int64_t timeout = 0LL,
|
||||
int64_t expiration = 0LL) = 0;
|
||||
|
||||
/**
|
||||
* Removes a pending task
|
||||
*/
|
||||
virtual void remove(boost::shared_ptr<Runnable> task) = 0;
|
||||
|
||||
/**
|
||||
* Remove the next pending task which would be run.
|
||||
*
|
||||
* @return the task removed.
|
||||
*/
|
||||
virtual boost::shared_ptr<Runnable> removeNextPending() = 0;
|
||||
|
||||
/**
|
||||
* Remove tasks from front of task queue that have expired.
|
||||
*/
|
||||
virtual void removeExpiredTasks() = 0;
|
||||
|
||||
/**
|
||||
* Set a callback to be called when a task is expired and not run.
|
||||
*
|
||||
* @param expireCallback a function called with the shared_ptr<Runnable> for
|
||||
* the expired task.
|
||||
*/
|
||||
virtual void setExpireCallback(ExpireCallback expireCallback) = 0;
|
||||
|
||||
static boost::shared_ptr<ThreadManager> newThreadManager();
|
||||
|
||||
/**
|
||||
* Creates a simple thread manager the uses count number of worker threads and has
|
||||
* a pendingTaskCountMax maximum pending tasks. The default, 0, specified no limit
|
||||
* on pending tasks
|
||||
*/
|
||||
static boost::shared_ptr<ThreadManager> newSimpleThreadManager(size_t count = 4,
|
||||
size_t pendingTaskCountMax = 0);
|
||||
|
||||
class Task;
|
||||
|
||||
class Worker;
|
||||
|
||||
class Impl;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
||||
|
||||
#endif // #ifndef _THRIFT_CONCURRENCY_THREADMANAGER_H_
|
305
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/TimerManager.cpp
generated
vendored
Normal file
305
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/TimerManager.cpp
generated
vendored
Normal file
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/concurrency/TimerManager.h>
|
||||
#include <thrift/concurrency/Exception.h>
|
||||
#include <thrift/concurrency/Util.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
using boost::shared_ptr;
|
||||
|
||||
/**
|
||||
* TimerManager class
|
||||
*
|
||||
* @version $Id:$
|
||||
*/
|
||||
class TimerManager::Task : public Runnable {
|
||||
|
||||
public:
|
||||
enum STATE { WAITING, EXECUTING, CANCELLED, COMPLETE };
|
||||
|
||||
Task(shared_ptr<Runnable> runnable) : runnable_(runnable), state_(WAITING) {}
|
||||
|
||||
~Task() {}
|
||||
|
||||
void run() {
|
||||
if (state_ == EXECUTING) {
|
||||
runnable_->run();
|
||||
state_ = COMPLETE;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
shared_ptr<Runnable> runnable_;
|
||||
friend class TimerManager::Dispatcher;
|
||||
STATE state_;
|
||||
};
|
||||
|
||||
class TimerManager::Dispatcher : public Runnable {
|
||||
|
||||
public:
|
||||
Dispatcher(TimerManager* manager) : manager_(manager) {}
|
||||
|
||||
~Dispatcher() {}
|
||||
|
||||
/**
|
||||
* Dispatcher entry point
|
||||
*
|
||||
* As long as dispatcher thread is running, pull tasks off the task taskMap_
|
||||
* and execute.
|
||||
*/
|
||||
void run() {
|
||||
{
|
||||
Synchronized s(manager_->monitor_);
|
||||
if (manager_->state_ == TimerManager::STARTING) {
|
||||
manager_->state_ = TimerManager::STARTED;
|
||||
manager_->monitor_.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
std::set<shared_ptr<TimerManager::Task> > expiredTasks;
|
||||
{
|
||||
Synchronized s(manager_->monitor_);
|
||||
task_iterator expiredTaskEnd;
|
||||
int64_t now = Util::currentTime();
|
||||
while (manager_->state_ == TimerManager::STARTED
|
||||
&& (expiredTaskEnd = manager_->taskMap_.upper_bound(now))
|
||||
== manager_->taskMap_.begin()) {
|
||||
int64_t timeout = 0LL;
|
||||
if (!manager_->taskMap_.empty()) {
|
||||
timeout = manager_->taskMap_.begin()->first - now;
|
||||
}
|
||||
assert((timeout != 0 && manager_->taskCount_ > 0)
|
||||
|| (timeout == 0 && manager_->taskCount_ == 0));
|
||||
try {
|
||||
manager_->monitor_.wait(timeout);
|
||||
} catch (TimedOutException&) {
|
||||
}
|
||||
now = Util::currentTime();
|
||||
}
|
||||
|
||||
if (manager_->state_ == TimerManager::STARTED) {
|
||||
for (task_iterator ix = manager_->taskMap_.begin(); ix != expiredTaskEnd; ix++) {
|
||||
shared_ptr<TimerManager::Task> task = ix->second;
|
||||
expiredTasks.insert(task);
|
||||
if (task->state_ == TimerManager::Task::WAITING) {
|
||||
task->state_ = TimerManager::Task::EXECUTING;
|
||||
}
|
||||
manager_->taskCount_--;
|
||||
}
|
||||
manager_->taskMap_.erase(manager_->taskMap_.begin(), expiredTaskEnd);
|
||||
}
|
||||
}
|
||||
|
||||
for (std::set<shared_ptr<Task> >::iterator ix = expiredTasks.begin();
|
||||
ix != expiredTasks.end();
|
||||
++ix) {
|
||||
(*ix)->run();
|
||||
}
|
||||
|
||||
} while (manager_->state_ == TimerManager::STARTED);
|
||||
|
||||
{
|
||||
Synchronized s(manager_->monitor_);
|
||||
if (manager_->state_ == TimerManager::STOPPING) {
|
||||
manager_->state_ = TimerManager::STOPPED;
|
||||
manager_->monitor_.notify();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
private:
|
||||
TimerManager* manager_;
|
||||
friend class TimerManager;
|
||||
};
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4355) // 'this' used in base member initializer list
|
||||
#endif
|
||||
|
||||
TimerManager::TimerManager()
|
||||
: taskCount_(0),
|
||||
state_(TimerManager::UNINITIALIZED),
|
||||
dispatcher_(shared_ptr<Dispatcher>(new Dispatcher(this))) {
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
TimerManager::~TimerManager() {
|
||||
|
||||
// If we haven't been explicitly stopped, do so now. We don't need to grab
|
||||
// the monitor here, since stop already takes care of reentrancy.
|
||||
|
||||
if (state_ != STOPPED) {
|
||||
try {
|
||||
stop();
|
||||
} catch (...) {
|
||||
// We're really hosed.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimerManager::start() {
|
||||
bool doStart = false;
|
||||
{
|
||||
Synchronized s(monitor_);
|
||||
if (!threadFactory_) {
|
||||
throw InvalidArgumentException();
|
||||
}
|
||||
if (state_ == TimerManager::UNINITIALIZED) {
|
||||
state_ = TimerManager::STARTING;
|
||||
doStart = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (doStart) {
|
||||
dispatcherThread_ = threadFactory_->newThread(dispatcher_);
|
||||
dispatcherThread_->start();
|
||||
}
|
||||
|
||||
{
|
||||
Synchronized s(monitor_);
|
||||
while (state_ == TimerManager::STARTING) {
|
||||
monitor_.wait();
|
||||
}
|
||||
assert(state_ != TimerManager::STARTING);
|
||||
}
|
||||
}
|
||||
|
||||
void TimerManager::stop() {
|
||||
bool doStop = false;
|
||||
{
|
||||
Synchronized s(monitor_);
|
||||
if (state_ == TimerManager::UNINITIALIZED) {
|
||||
state_ = TimerManager::STOPPED;
|
||||
} else if (state_ != STOPPING && state_ != STOPPED) {
|
||||
doStop = true;
|
||||
state_ = STOPPING;
|
||||
monitor_.notifyAll();
|
||||
}
|
||||
while (state_ != STOPPED) {
|
||||
monitor_.wait();
|
||||
}
|
||||
}
|
||||
|
||||
if (doStop) {
|
||||
// Clean up any outstanding tasks
|
||||
taskMap_.clear();
|
||||
|
||||
// Remove dispatcher's reference to us.
|
||||
dispatcher_->manager_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<const ThreadFactory> TimerManager::threadFactory() const {
|
||||
Synchronized s(monitor_);
|
||||
return threadFactory_;
|
||||
}
|
||||
|
||||
void TimerManager::threadFactory(shared_ptr<const ThreadFactory> value) {
|
||||
Synchronized s(monitor_);
|
||||
threadFactory_ = value;
|
||||
}
|
||||
|
||||
size_t TimerManager::taskCount() const {
|
||||
return taskCount_;
|
||||
}
|
||||
|
||||
void TimerManager::add(shared_ptr<Runnable> task, int64_t timeout) {
|
||||
int64_t now = Util::currentTime();
|
||||
timeout += now;
|
||||
|
||||
{
|
||||
Synchronized s(monitor_);
|
||||
if (state_ != TimerManager::STARTED) {
|
||||
throw IllegalStateException();
|
||||
}
|
||||
|
||||
// If the task map is empty, we will kick the dispatcher for sure. Otherwise, we kick him
|
||||
// if the expiration time is shorter than the current value. Need to test before we insert,
|
||||
// because the new task might insert at the front.
|
||||
bool notifyRequired = (taskCount_ == 0) ? true : timeout < taskMap_.begin()->first;
|
||||
|
||||
taskCount_++;
|
||||
taskMap_.insert(
|
||||
std::pair<int64_t, shared_ptr<Task> >(timeout, shared_ptr<Task>(new Task(task))));
|
||||
|
||||
// If the task map was empty, or if we have an expiration that is earlier
|
||||
// than any previously seen, kick the dispatcher so it can update its
|
||||
// timeout
|
||||
if (notifyRequired) {
|
||||
monitor_.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimerManager::add(shared_ptr<Runnable> task, const struct THRIFT_TIMESPEC& value) {
|
||||
|
||||
int64_t expiration;
|
||||
Util::toMilliseconds(expiration, value);
|
||||
|
||||
int64_t now = Util::currentTime();
|
||||
|
||||
if (expiration < now) {
|
||||
throw InvalidArgumentException();
|
||||
}
|
||||
|
||||
add(task, expiration - now);
|
||||
}
|
||||
|
||||
void TimerManager::add(shared_ptr<Runnable> task, const struct timeval& value) {
|
||||
|
||||
int64_t expiration;
|
||||
Util::toMilliseconds(expiration, value);
|
||||
|
||||
int64_t now = Util::currentTime();
|
||||
|
||||
if (expiration < now) {
|
||||
throw InvalidArgumentException();
|
||||
}
|
||||
|
||||
add(task, expiration - now);
|
||||
}
|
||||
|
||||
void TimerManager::remove(shared_ptr<Runnable> task) {
|
||||
(void)task;
|
||||
Synchronized s(monitor_);
|
||||
if (state_ != TimerManager::STARTED) {
|
||||
throw IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
TimerManager::STATE TimerManager::state() const {
|
||||
return state_;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
126
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/TimerManager.h
generated
vendored
Normal file
126
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/TimerManager.h
generated
vendored
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_CONCURRENCY_TIMERMANAGER_H_
|
||||
#define _THRIFT_CONCURRENCY_TIMERMANAGER_H_ 1
|
||||
|
||||
#include <thrift/concurrency/Exception.h>
|
||||
#include <thrift/concurrency/Monitor.h>
|
||||
#include <thrift/concurrency/Thread.h>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <map>
|
||||
#include <time.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
/**
|
||||
* Timer Manager
|
||||
*
|
||||
* This class dispatches timer tasks when they fall due.
|
||||
*
|
||||
* @version $Id:$
|
||||
*/
|
||||
class TimerManager {
|
||||
|
||||
public:
|
||||
TimerManager();
|
||||
|
||||
virtual ~TimerManager();
|
||||
|
||||
virtual boost::shared_ptr<const ThreadFactory> threadFactory() const;
|
||||
|
||||
virtual void threadFactory(boost::shared_ptr<const ThreadFactory> value);
|
||||
|
||||
/**
|
||||
* Starts the timer manager service
|
||||
*
|
||||
* @throws IllegalArgumentException Missing thread factory attribute
|
||||
*/
|
||||
virtual void start();
|
||||
|
||||
/**
|
||||
* Stops the timer manager service
|
||||
*/
|
||||
virtual void stop();
|
||||
|
||||
virtual size_t taskCount() const;
|
||||
|
||||
/**
|
||||
* Adds a task to be executed at some time in the future by a worker thread.
|
||||
*
|
||||
* @param task The task to execute
|
||||
* @param timeout Time in milliseconds to delay before executing task
|
||||
*/
|
||||
virtual void add(boost::shared_ptr<Runnable> task, int64_t timeout);
|
||||
|
||||
/**
|
||||
* Adds a task to be executed at some time in the future by a worker thread.
|
||||
*
|
||||
* @param task The task to execute
|
||||
* @param timeout Absolute time in the future to execute task.
|
||||
*/
|
||||
virtual void add(boost::shared_ptr<Runnable> task, const struct THRIFT_TIMESPEC& timeout);
|
||||
|
||||
/**
|
||||
* Adds a task to be executed at some time in the future by a worker thread.
|
||||
*
|
||||
* @param task The task to execute
|
||||
* @param timeout Absolute time in the future to execute task.
|
||||
*/
|
||||
virtual void add(boost::shared_ptr<Runnable> task, const struct timeval& timeout);
|
||||
|
||||
/**
|
||||
* Removes a pending task
|
||||
*
|
||||
* @throws NoSuchTaskException Specified task doesn't exist. It was either
|
||||
* processed already or this call was made for a
|
||||
* task that was never added to this timer
|
||||
*
|
||||
* @throws UncancellableTaskException Specified task is already being
|
||||
* executed or has completed execution.
|
||||
*/
|
||||
virtual void remove(boost::shared_ptr<Runnable> task);
|
||||
|
||||
enum STATE { UNINITIALIZED, STARTING, STARTED, STOPPING, STOPPED };
|
||||
|
||||
virtual STATE state() const;
|
||||
|
||||
private:
|
||||
boost::shared_ptr<const ThreadFactory> threadFactory_;
|
||||
class Task;
|
||||
friend class Task;
|
||||
std::multimap<int64_t, boost::shared_ptr<Task> > taskMap_;
|
||||
size_t taskCount_;
|
||||
Monitor monitor_;
|
||||
STATE state_;
|
||||
class Dispatcher;
|
||||
friend class Dispatcher;
|
||||
boost::shared_ptr<Dispatcher> dispatcher_;
|
||||
boost::shared_ptr<Thread> dispatcherThread_;
|
||||
typedef std::multimap<int64_t, boost::shared_ptr<TimerManager::Task> >::iterator task_iterator;
|
||||
typedef std::pair<task_iterator, task_iterator> task_range;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
||||
|
||||
#endif // #ifndef _THRIFT_CONCURRENCY_TIMERMANAGER_H_
|
44
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/Util.cpp
generated
vendored
Normal file
44
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/Util.cpp
generated
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/thrift-config.h>
|
||||
|
||||
#include <thrift/Thrift.h>
|
||||
#include <thrift/concurrency/Util.h>
|
||||
|
||||
#if defined(HAVE_SYS_TIME_H)
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
int64_t Util::currentTimeTicks(int64_t ticksPerSec) {
|
||||
int64_t result;
|
||||
struct timeval now;
|
||||
int ret = THRIFT_GETTIMEOFDAY(&now, NULL);
|
||||
assert(ret == 0);
|
||||
THRIFT_UNUSED_VARIABLE(ret); // squelching "unused variable" warning
|
||||
toTicks(result, now, ticksPerSec);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
151
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/Util.h
generated
vendored
Normal file
151
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/concurrency/Util.h
generated
vendored
Normal file
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_CONCURRENCY_UTIL_H_
|
||||
#define _THRIFT_CONCURRENCY_UTIL_H_ 1
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <thrift/transport/PlatformSocket.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace concurrency {
|
||||
|
||||
/**
|
||||
* Utility methods
|
||||
*
|
||||
* This class contains basic utility methods for converting time formats,
|
||||
* and other common platform-dependent concurrency operations.
|
||||
* It should not be included in API headers for other concurrency library
|
||||
* headers, since it will, by definition, pull in all sorts of horrid
|
||||
* platform dependent stuff. Rather it should be inluded directly in
|
||||
* concurrency library implementation source.
|
||||
*
|
||||
* @version $Id:$
|
||||
*/
|
||||
class Util {
|
||||
|
||||
static const int64_t NS_PER_S = 1000000000LL;
|
||||
static const int64_t US_PER_S = 1000000LL;
|
||||
static const int64_t MS_PER_S = 1000LL;
|
||||
|
||||
static const int64_t NS_PER_MS = NS_PER_S / MS_PER_S;
|
||||
static const int64_t NS_PER_US = NS_PER_S / US_PER_S;
|
||||
static const int64_t US_PER_MS = US_PER_S / MS_PER_S;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Converts millisecond timestamp into a THRIFT_TIMESPEC struct
|
||||
*
|
||||
* @param struct THRIFT_TIMESPEC& result
|
||||
* @param time or duration in milliseconds
|
||||
*/
|
||||
static void toTimespec(struct THRIFT_TIMESPEC& result, int64_t value) {
|
||||
result.tv_sec = value / MS_PER_S; // ms to s
|
||||
result.tv_nsec = (value % MS_PER_S) * NS_PER_MS; // ms to ns
|
||||
}
|
||||
|
||||
static void toTimeval(struct timeval& result, int64_t value) {
|
||||
result.tv_sec = static_cast<uint32_t>(value / MS_PER_S); // ms to s
|
||||
result.tv_usec = static_cast<uint32_t>((value % MS_PER_S) * US_PER_MS); // ms to us
|
||||
}
|
||||
|
||||
static void toTicks(int64_t& result,
|
||||
int64_t secs,
|
||||
int64_t oldTicks,
|
||||
int64_t oldTicksPerSec,
|
||||
int64_t newTicksPerSec) {
|
||||
result = secs * newTicksPerSec;
|
||||
result += oldTicks * newTicksPerSec / oldTicksPerSec;
|
||||
|
||||
int64_t oldPerNew = oldTicksPerSec / newTicksPerSec;
|
||||
if (oldPerNew && ((oldTicks % oldPerNew) >= (oldPerNew / 2))) {
|
||||
++result;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Converts struct THRIFT_TIMESPEC to arbitrary-sized ticks since epoch
|
||||
*/
|
||||
static void toTicks(int64_t& result, const struct THRIFT_TIMESPEC& value, int64_t ticksPerSec) {
|
||||
return toTicks(result, value.tv_sec, value.tv_nsec, NS_PER_S, ticksPerSec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts struct timeval to arbitrary-sized ticks since epoch
|
||||
*/
|
||||
static void toTicks(int64_t& result, const struct timeval& value, int64_t ticksPerSec) {
|
||||
return toTicks(result, (unsigned long)value.tv_sec, (unsigned long)value.tv_usec, US_PER_S, ticksPerSec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts struct THRIFT_TIMESPEC to milliseconds
|
||||
*/
|
||||
static void toMilliseconds(int64_t& result, const struct THRIFT_TIMESPEC& value) {
|
||||
return toTicks(result, value, MS_PER_S);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts struct timeval to milliseconds
|
||||
*/
|
||||
static void toMilliseconds(int64_t& result, const struct timeval& value) {
|
||||
return toTicks(result, value, MS_PER_S);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts struct THRIFT_TIMESPEC to microseconds
|
||||
*/
|
||||
static void toUsec(int64_t& result, const struct THRIFT_TIMESPEC& value) {
|
||||
return toTicks(result, value, US_PER_S);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts struct timeval to microseconds
|
||||
*/
|
||||
static void toUsec(int64_t& result, const struct timeval& value) {
|
||||
return toTicks(result, value, US_PER_S);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current time as a number of arbitrary-size ticks from epoch
|
||||
*/
|
||||
static int64_t currentTimeTicks(int64_t ticksPerSec);
|
||||
|
||||
/**
|
||||
* Get current time as milliseconds from epoch
|
||||
*/
|
||||
static int64_t currentTime() { return currentTimeTicks(MS_PER_S); }
|
||||
|
||||
/**
|
||||
* Get current time as micros from epoch
|
||||
*/
|
||||
static int64_t currentTimeUsec() { return currentTimeTicks(US_PER_S); }
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::concurrency
|
||||
|
||||
#endif // #ifndef _THRIFT_CONCURRENCY_UTIL_H_
|
132
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/cxxfunctional.h
generated
vendored
Normal file
132
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/cxxfunctional.h
generated
vendored
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_CXXFUNCTIONAL_H_
|
||||
#define _THRIFT_CXXFUNCTIONAL_H_ 1
|
||||
|
||||
// clang-format off
|
||||
|
||||
/**
|
||||
* Loads <functional> from the 'right' location, depending
|
||||
* on compiler and whether or not it's using C++03 with TR1
|
||||
* or C++11.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MSVC 10 and 11 have the <functional> stuff at <functional>.
|
||||
* In MSVC 10 all of the implementations live in std::tr1.
|
||||
* In MSVC 11 all of the implementations live in std, with aliases
|
||||
* in std::tr1 to point to the ones in std.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||
#define _THRIFT_USING_MICROSOFT_STDLIB 1
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
/* Clang has two options, depending on standard library:
|
||||
* - no -stdlib or -stdlib=libstdc++ set; uses GNU libstdc++.
|
||||
* <tr1/functional>
|
||||
* - -stdlib=libc++; uses LLVM libc++.
|
||||
* <functional>, no 'std::tr1'.
|
||||
*
|
||||
* The compiler itself doesn't define anything differently
|
||||
* depending on the value of -stdlib, but the library headers
|
||||
* will set different preprocessor options. In order to check,
|
||||
* though, we have to pull in some library header.
|
||||
*/
|
||||
#include <utility>
|
||||
|
||||
/* With LLVM libc++, utility pulls in __config, which sets
|
||||
_LIBCPP_VERSION. */
|
||||
#if defined(_LIBCPP_VERSION)
|
||||
#define _THRIFT_USING_CLANG_LIBCXX 1
|
||||
|
||||
/* With GNU libstdc++, utility pulls in bits/c++config.h,
|
||||
which sets __GLIBCXX__. */
|
||||
#elif defined(__GLIBCXX__)
|
||||
#define _THRIFT_USING_GNU_LIBSTDCXX 1
|
||||
|
||||
/* No idea. */
|
||||
#else
|
||||
#error Unable to detect which C++ standard library is in use.
|
||||
#endif
|
||||
#elif __GNUC__
|
||||
#define _THRIFT_USING_GNU_LIBSTDCXX 1
|
||||
#endif
|
||||
|
||||
#if _THRIFT_USING_MICROSOFT_STDLIB
|
||||
#include <functional>
|
||||
|
||||
namespace apache { namespace thrift { namespace stdcxx {
|
||||
using ::std::tr1::function;
|
||||
using ::std::tr1::bind;
|
||||
|
||||
namespace placeholders {
|
||||
using ::std::tr1::placeholders::_1;
|
||||
using ::std::tr1::placeholders::_2;
|
||||
using ::std::tr1::placeholders::_3;
|
||||
using ::std::tr1::placeholders::_4;
|
||||
using ::std::tr1::placeholders::_5;
|
||||
using ::std::tr1::placeholders::_6;
|
||||
} // apache::thrift::stdcxx::placeholders
|
||||
}}} // apache::thrift::stdcxx
|
||||
|
||||
#elif _THRIFT_USING_CLANG_LIBCXX
|
||||
#include <functional>
|
||||
|
||||
namespace apache { namespace thrift { namespace stdcxx {
|
||||
using ::std::function;
|
||||
using ::std::bind;
|
||||
|
||||
namespace placeholders {
|
||||
using ::std::placeholders::_1;
|
||||
using ::std::placeholders::_2;
|
||||
using ::std::placeholders::_3;
|
||||
using ::std::placeholders::_4;
|
||||
using ::std::placeholders::_5;
|
||||
using ::std::placeholders::_6;
|
||||
} // apache::thrift::stdcxx::placeholders
|
||||
}}} // apache::thrift::stdcxx
|
||||
|
||||
#elif _THRIFT_USING_GNU_LIBSTDCXX
|
||||
#ifdef USE_BOOST_THREAD
|
||||
#include <boost/tr1/functional.hpp>
|
||||
#else
|
||||
#include <tr1/functional>
|
||||
#endif
|
||||
|
||||
namespace apache { namespace thrift { namespace stdcxx {
|
||||
using ::std::tr1::function;
|
||||
using ::std::tr1::bind;
|
||||
|
||||
namespace placeholders {
|
||||
using ::std::tr1::placeholders::_1;
|
||||
using ::std::tr1::placeholders::_2;
|
||||
using ::std::tr1::placeholders::_3;
|
||||
using ::std::tr1::placeholders::_4;
|
||||
using ::std::tr1::placeholders::_5;
|
||||
using ::std::tr1::placeholders::_6;
|
||||
} // apache::thrift::stdcxx::placeholders
|
||||
}}} // apache::thrift::stdcxx
|
||||
#endif
|
||||
|
||||
// Alias for thrift c++ compatibility namespace
|
||||
namespace tcxx = apache::thrift::stdcxx;
|
||||
|
||||
#endif // #ifndef _THRIFT_CXXFUNCTIONAL_H_
|
132
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/processor/PeekProcessor.cpp
generated
vendored
Normal file
132
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/processor/PeekProcessor.cpp
generated
vendored
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/processor/PeekProcessor.h>
|
||||
|
||||
using namespace apache::thrift::transport;
|
||||
using namespace apache::thrift::protocol;
|
||||
using namespace apache::thrift;
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace processor {
|
||||
|
||||
PeekProcessor::PeekProcessor() {
|
||||
memoryBuffer_.reset(new TMemoryBuffer());
|
||||
targetTransport_ = memoryBuffer_;
|
||||
}
|
||||
PeekProcessor::~PeekProcessor() {
|
||||
}
|
||||
|
||||
void PeekProcessor::initialize(boost::shared_ptr<TProcessor> actualProcessor,
|
||||
boost::shared_ptr<TProtocolFactory> protocolFactory,
|
||||
boost::shared_ptr<TPipedTransportFactory> transportFactory) {
|
||||
actualProcessor_ = actualProcessor;
|
||||
pipedProtocol_ = protocolFactory->getProtocol(targetTransport_);
|
||||
transportFactory_ = transportFactory;
|
||||
transportFactory_->initializeTargetTransport(targetTransport_);
|
||||
}
|
||||
|
||||
boost::shared_ptr<TTransport> PeekProcessor::getPipedTransport(boost::shared_ptr<TTransport> in) {
|
||||
return transportFactory_->getTransport(in);
|
||||
}
|
||||
|
||||
void PeekProcessor::setTargetTransport(boost::shared_ptr<TTransport> targetTransport) {
|
||||
targetTransport_ = targetTransport;
|
||||
if (boost::dynamic_pointer_cast<TMemoryBuffer>(targetTransport_)) {
|
||||
memoryBuffer_ = boost::dynamic_pointer_cast<TMemoryBuffer>(targetTransport);
|
||||
} else if (boost::dynamic_pointer_cast<TPipedTransport>(targetTransport_)) {
|
||||
memoryBuffer_ = boost::dynamic_pointer_cast<TMemoryBuffer>(
|
||||
boost::dynamic_pointer_cast<TPipedTransport>(targetTransport_)->getTargetTransport());
|
||||
}
|
||||
|
||||
if (!memoryBuffer_) {
|
||||
throw TException(
|
||||
"Target transport must be a TMemoryBuffer or a TPipedTransport with TMemoryBuffer");
|
||||
}
|
||||
}
|
||||
|
||||
bool PeekProcessor::process(boost::shared_ptr<TProtocol> in,
|
||||
boost::shared_ptr<TProtocol> out,
|
||||
void* connectionContext) {
|
||||
|
||||
std::string fname;
|
||||
TMessageType mtype;
|
||||
int32_t seqid;
|
||||
in->readMessageBegin(fname, mtype, seqid);
|
||||
|
||||
if (mtype != T_CALL && mtype != T_ONEWAY) {
|
||||
throw TException("Unexpected message type");
|
||||
}
|
||||
|
||||
// Peek at the name
|
||||
peekName(fname);
|
||||
|
||||
TType ftype;
|
||||
int16_t fid;
|
||||
while (true) {
|
||||
in->readFieldBegin(fname, ftype, fid);
|
||||
if (ftype == T_STOP) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Peek at the variable
|
||||
peek(in, ftype, fid);
|
||||
in->readFieldEnd();
|
||||
}
|
||||
in->readMessageEnd();
|
||||
in->getTransport()->readEnd();
|
||||
|
||||
//
|
||||
// All the data is now in memoryBuffer_ and ready to be processed
|
||||
//
|
||||
|
||||
// Let's first take a peek at the full data in memory
|
||||
uint8_t* buffer;
|
||||
uint32_t size;
|
||||
memoryBuffer_->getBuffer(&buffer, &size);
|
||||
peekBuffer(buffer, size);
|
||||
|
||||
// Done peeking at variables
|
||||
peekEnd();
|
||||
|
||||
bool ret = actualProcessor_->process(pipedProtocol_, out, connectionContext);
|
||||
memoryBuffer_->resetBuffer();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PeekProcessor::peekName(const std::string& fname) {
|
||||
(void)fname;
|
||||
}
|
||||
|
||||
void PeekProcessor::peekBuffer(uint8_t* buffer, uint32_t size) {
|
||||
(void)buffer;
|
||||
(void)size;
|
||||
}
|
||||
|
||||
void PeekProcessor::peek(boost::shared_ptr<TProtocol> in, TType ftype, int16_t fid) {
|
||||
(void)fid;
|
||||
in->skip(ftype);
|
||||
}
|
||||
|
||||
void PeekProcessor::peekEnd() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
83
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/processor/PeekProcessor.h
generated
vendored
Normal file
83
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/processor/PeekProcessor.h
generated
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef PEEKPROCESSOR_H
|
||||
#define PEEKPROCESSOR_H
|
||||
|
||||
#include <string>
|
||||
#include <thrift/TProcessor.h>
|
||||
#include <thrift/transport/TTransport.h>
|
||||
#include <thrift/transport/TTransportUtils.h>
|
||||
#include <thrift/transport/TBufferTransports.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace processor {
|
||||
|
||||
/*
|
||||
* Class for peeking at the raw data that is being processed by another processor
|
||||
* and gives the derived class a chance to change behavior accordingly
|
||||
*
|
||||
*/
|
||||
class PeekProcessor : public apache::thrift::TProcessor {
|
||||
|
||||
public:
|
||||
PeekProcessor();
|
||||
virtual ~PeekProcessor();
|
||||
|
||||
// Input here: actualProcessor - the underlying processor
|
||||
// protocolFactory - the protocol factory used to wrap the memory buffer
|
||||
// transportFactory - this TPipedTransportFactory is used to wrap the source transport
|
||||
// via a call to getPipedTransport
|
||||
void initialize(
|
||||
boost::shared_ptr<apache::thrift::TProcessor> actualProcessor,
|
||||
boost::shared_ptr<apache::thrift::protocol::TProtocolFactory> protocolFactory,
|
||||
boost::shared_ptr<apache::thrift::transport::TPipedTransportFactory> transportFactory);
|
||||
|
||||
boost::shared_ptr<apache::thrift::transport::TTransport> getPipedTransport(
|
||||
boost::shared_ptr<apache::thrift::transport::TTransport> in);
|
||||
|
||||
void setTargetTransport(boost::shared_ptr<apache::thrift::transport::TTransport> targetTransport);
|
||||
|
||||
virtual bool process(boost::shared_ptr<apache::thrift::protocol::TProtocol> in,
|
||||
boost::shared_ptr<apache::thrift::protocol::TProtocol> out,
|
||||
void* connectionContext);
|
||||
|
||||
// The following three functions can be overloaded by child classes to
|
||||
// achieve desired peeking behavior
|
||||
virtual void peekName(const std::string& fname);
|
||||
virtual void peekBuffer(uint8_t* buffer, uint32_t size);
|
||||
virtual void peek(boost::shared_ptr<apache::thrift::protocol::TProtocol> in,
|
||||
apache::thrift::protocol::TType ftype,
|
||||
int16_t fid);
|
||||
virtual void peekEnd();
|
||||
|
||||
private:
|
||||
boost::shared_ptr<apache::thrift::TProcessor> actualProcessor_;
|
||||
boost::shared_ptr<apache::thrift::protocol::TProtocol> pipedProtocol_;
|
||||
boost::shared_ptr<apache::thrift::transport::TPipedTransportFactory> transportFactory_;
|
||||
boost::shared_ptr<apache::thrift::transport::TMemoryBuffer> memoryBuffer_;
|
||||
boost::shared_ptr<apache::thrift::transport::TTransport> targetTransport_;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::processor
|
||||
|
||||
#endif
|
242
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/processor/StatsProcessor.h
generated
vendored
Normal file
242
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/processor/StatsProcessor.h
generated
vendored
Normal file
|
@ -0,0 +1,242 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef STATSPROCESSOR_H
|
||||
#define STATSPROCESSOR_H
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <thrift/transport/TTransport.h>
|
||||
#include <thrift/protocol/TProtocol.h>
|
||||
#include <TProcessor.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace processor {
|
||||
|
||||
/*
|
||||
* Class for keeping track of function call statistics and printing them if desired
|
||||
*
|
||||
*/
|
||||
class StatsProcessor : public apache::thrift::TProcessor {
|
||||
public:
|
||||
StatsProcessor(bool print, bool frequency) : print_(print), frequency_(frequency) {}
|
||||
virtual ~StatsProcessor(){};
|
||||
|
||||
virtual bool process(boost::shared_ptr<apache::thrift::protocol::TProtocol> piprot,
|
||||
boost::shared_ptr<apache::thrift::protocol::TProtocol> poprot,
|
||||
void* serverContext) {
|
||||
|
||||
piprot_ = piprot;
|
||||
|
||||
std::string fname;
|
||||
apache::thrift::protocol::TMessageType mtype;
|
||||
int32_t seqid;
|
||||
|
||||
piprot_->readMessageBegin(fname, mtype, seqid);
|
||||
if (mtype != apache::thrift::protocol::T_CALL && mtype != apache::thrift::protocol::T_ONEWAY) {
|
||||
if (print_) {
|
||||
printf("Unknown message type\n");
|
||||
}
|
||||
throw apache::thrift::TException("Unexpected message type");
|
||||
}
|
||||
if (print_) {
|
||||
printf("%s (", fname.c_str());
|
||||
}
|
||||
if (frequency_) {
|
||||
if (frequency_map_.find(fname) != frequency_map_.end()) {
|
||||
frequency_map_[fname]++;
|
||||
} else {
|
||||
frequency_map_[fname] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
apache::thrift::protocol::TType ftype;
|
||||
int16_t fid;
|
||||
|
||||
while (true) {
|
||||
piprot_->readFieldBegin(fname, ftype, fid);
|
||||
if (ftype == apache::thrift::protocol::T_STOP) {
|
||||
break;
|
||||
}
|
||||
|
||||
printAndPassToBuffer(ftype);
|
||||
if (print_) {
|
||||
printf(", ");
|
||||
}
|
||||
}
|
||||
|
||||
if (print_) {
|
||||
printf("\b\b)\n");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::map<std::string, int64_t>& get_frequency_map() { return frequency_map_; }
|
||||
|
||||
protected:
|
||||
void printAndPassToBuffer(apache::thrift::protocol::TType ftype) {
|
||||
switch (ftype) {
|
||||
case apache::thrift::protocol::T_BOOL: {
|
||||
bool boolv;
|
||||
piprot_->readBool(boolv);
|
||||
if (print_) {
|
||||
printf("%d", boolv);
|
||||
}
|
||||
} break;
|
||||
case apache::thrift::protocol::T_BYTE: {
|
||||
int8_t bytev;
|
||||
piprot_->readByte(bytev);
|
||||
if (print_) {
|
||||
printf("%d", bytev);
|
||||
}
|
||||
} break;
|
||||
case apache::thrift::protocol::T_I16: {
|
||||
int16_t i16;
|
||||
piprot_->readI16(i16);
|
||||
if (print_) {
|
||||
printf("%d", i16);
|
||||
}
|
||||
} break;
|
||||
case apache::thrift::protocol::T_I32: {
|
||||
int32_t i32;
|
||||
piprot_->readI32(i32);
|
||||
if (print_) {
|
||||
printf("%d", i32);
|
||||
}
|
||||
} break;
|
||||
case apache::thrift::protocol::T_I64: {
|
||||
int64_t i64;
|
||||
piprot_->readI64(i64);
|
||||
if (print_) {
|
||||
printf("%ld", i64);
|
||||
}
|
||||
} break;
|
||||
case apache::thrift::protocol::T_DOUBLE: {
|
||||
double dub;
|
||||
piprot_->readDouble(dub);
|
||||
if (print_) {
|
||||
printf("%f", dub);
|
||||
}
|
||||
} break;
|
||||
case apache::thrift::protocol::T_STRING: {
|
||||
std::string str;
|
||||
piprot_->readString(str);
|
||||
if (print_) {
|
||||
printf("%s", str.c_str());
|
||||
}
|
||||
} break;
|
||||
case apache::thrift::protocol::T_STRUCT: {
|
||||
std::string name;
|
||||
int16_t fid;
|
||||
apache::thrift::protocol::TType ftype;
|
||||
piprot_->readStructBegin(name);
|
||||
if (print_) {
|
||||
printf("<");
|
||||
}
|
||||
while (true) {
|
||||
piprot_->readFieldBegin(name, ftype, fid);
|
||||
if (ftype == apache::thrift::protocol::T_STOP) {
|
||||
break;
|
||||
}
|
||||
printAndPassToBuffer(ftype);
|
||||
if (print_) {
|
||||
printf(",");
|
||||
}
|
||||
piprot_->readFieldEnd();
|
||||
}
|
||||
piprot_->readStructEnd();
|
||||
if (print_) {
|
||||
printf("\b>");
|
||||
}
|
||||
} break;
|
||||
case apache::thrift::protocol::T_MAP: {
|
||||
apache::thrift::protocol::TType keyType;
|
||||
apache::thrift::protocol::TType valType;
|
||||
uint32_t i, size;
|
||||
piprot_->readMapBegin(keyType, valType, size);
|
||||
if (print_) {
|
||||
printf("{");
|
||||
}
|
||||
for (i = 0; i < size; i++) {
|
||||
printAndPassToBuffer(keyType);
|
||||
if (print_) {
|
||||
printf("=>");
|
||||
}
|
||||
printAndPassToBuffer(valType);
|
||||
if (print_) {
|
||||
printf(",");
|
||||
}
|
||||
}
|
||||
piprot_->readMapEnd();
|
||||
if (print_) {
|
||||
printf("\b}");
|
||||
}
|
||||
} break;
|
||||
case apache::thrift::protocol::T_SET: {
|
||||
apache::thrift::protocol::TType elemType;
|
||||
uint32_t i, size;
|
||||
piprot_->readSetBegin(elemType, size);
|
||||
if (print_) {
|
||||
printf("{");
|
||||
}
|
||||
for (i = 0; i < size; i++) {
|
||||
printAndPassToBuffer(elemType);
|
||||
if (print_) {
|
||||
printf(",");
|
||||
}
|
||||
}
|
||||
piprot_->readSetEnd();
|
||||
if (print_) {
|
||||
printf("\b}");
|
||||
}
|
||||
} break;
|
||||
case apache::thrift::protocol::T_LIST: {
|
||||
apache::thrift::protocol::TType elemType;
|
||||
uint32_t i, size;
|
||||
piprot_->readListBegin(elemType, size);
|
||||
if (print_) {
|
||||
printf("[");
|
||||
}
|
||||
for (i = 0; i < size; i++) {
|
||||
printAndPassToBuffer(elemType);
|
||||
if (print_) {
|
||||
printf(",");
|
||||
}
|
||||
}
|
||||
piprot_->readListEnd();
|
||||
if (print_) {
|
||||
printf("\b]");
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<apache::thrift::protocol::TProtocol> piprot_;
|
||||
std::map<std::string, int64_t> frequency_map_;
|
||||
|
||||
bool print_;
|
||||
bool frequency_;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::processor
|
||||
|
||||
#endif
|
201
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/processor/TMultiplexedProcessor.h
generated
vendored
Normal file
201
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/processor/TMultiplexedProcessor.h
generated
vendored
Normal file
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef THRIFT_TMULTIPLEXEDPROCESSOR_H_
|
||||
#define THRIFT_TMULTIPLEXEDPROCESSOR_H_ 1
|
||||
|
||||
#include <thrift/protocol/TProtocolDecorator.h>
|
||||
#include <thrift/TApplicationException.h>
|
||||
#include <thrift/TProcessor.h>
|
||||
#include <boost/tokenizer.hpp>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
using boost::shared_ptr;
|
||||
|
||||
namespace protocol {
|
||||
|
||||
/**
|
||||
* To be able to work with any protocol, we needed
|
||||
* to allow them to call readMessageBegin() and get a TMessage in exactly
|
||||
* the standard format, without the service name prepended to TMessage.name.
|
||||
*/
|
||||
class StoredMessageProtocol : public TProtocolDecorator {
|
||||
public:
|
||||
StoredMessageProtocol(shared_ptr<protocol::TProtocol> _protocol,
|
||||
const std::string& _name,
|
||||
const TMessageType _type,
|
||||
const int32_t _seqid)
|
||||
: TProtocolDecorator(_protocol), name(_name), type(_type), seqid(_seqid) {}
|
||||
|
||||
uint32_t readMessageBegin_virt(std::string& _name, TMessageType& _type, int32_t& _seqid) {
|
||||
|
||||
_name = name;
|
||||
_type = type;
|
||||
_seqid = seqid;
|
||||
|
||||
return 0; // (Normal TProtocol read functions return number of bytes read)
|
||||
}
|
||||
|
||||
std::string name;
|
||||
TMessageType type;
|
||||
int32_t seqid;
|
||||
};
|
||||
} // namespace protocol
|
||||
|
||||
/**
|
||||
* <code>TMultiplexedProcessor</code> is a <code>TProcessor</code> allowing
|
||||
* a single <code>TServer</code> to provide multiple services.
|
||||
*
|
||||
* <p>To do so, you instantiate the processor and then register additional
|
||||
* processors with it, as shown in the following example:</p>
|
||||
*
|
||||
* <blockquote><code>
|
||||
* shared_ptr<TMultiplexedProcessor> processor(new TMultiplexedProcessor());
|
||||
*
|
||||
* processor->registerProcessor(
|
||||
* "Calculator",
|
||||
* shared_ptr<TProcessor>( new CalculatorProcessor(
|
||||
* shared_ptr<CalculatorHandler>( new CalculatorHandler()))));
|
||||
*
|
||||
* processor->registerProcessor(
|
||||
* "WeatherReport",
|
||||
* shared_ptr<TProcessor>( new WeatherReportProcessor(
|
||||
* shared_ptr<WeatherReportHandler>( new WeatherReportHandler()))));
|
||||
*
|
||||
* shared_ptr<TServerTransport> transport(new TServerSocket(9090));
|
||||
* TSimpleServer server(processor, transport);
|
||||
*
|
||||
* server.serve();
|
||||
* </code></blockquote>
|
||||
*/
|
||||
class TMultiplexedProcessor : public TProcessor {
|
||||
public:
|
||||
typedef std::map<std::string, shared_ptr<TProcessor> > services_t;
|
||||
|
||||
/**
|
||||
* 'Register' a service with this <code>TMultiplexedProcessor</code>. This
|
||||
* allows us to broker requests to individual services by using the service
|
||||
* name to select them at request time.
|
||||
*
|
||||
* \param [in] serviceName Name of a service, has to be identical to the name
|
||||
* declared in the Thrift IDL, e.g. "WeatherReport".
|
||||
* \param [in] processor Implementation of a service, usually referred to
|
||||
* as "handlers", e.g. WeatherReportHandler,
|
||||
* implementing WeatherReportIf interface.
|
||||
*/
|
||||
void registerProcessor(const std::string& serviceName, shared_ptr<TProcessor> processor) {
|
||||
services[serviceName] = processor;
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation of <code>process</code> performs the following steps:
|
||||
*
|
||||
* <ol>
|
||||
* <li>Read the beginning of the message.</li>
|
||||
* <li>Extract the service name from the message.</li>
|
||||
* <li>Using the service name to locate the appropriate processor.</li>
|
||||
* <li>Dispatch to the processor, with a decorated instance of TProtocol
|
||||
* that allows readMessageBegin() to return the original TMessage.</li>
|
||||
* </ol>
|
||||
*
|
||||
* \throws TException If the message type is not T_CALL or T_ONEWAY, if
|
||||
* the service name was not found in the message, or if the service
|
||||
* name was not found in the service map.
|
||||
*/
|
||||
bool process(shared_ptr<protocol::TProtocol> in,
|
||||
shared_ptr<protocol::TProtocol> out,
|
||||
void* connectionContext) {
|
||||
std::string name;
|
||||
protocol::TMessageType type;
|
||||
int32_t seqid;
|
||||
|
||||
// Use the actual underlying protocol (e.g. TBinaryProtocol) to read the
|
||||
// message header. This pulls the message "off the wire", which we'll
|
||||
// deal with at the end of this method.
|
||||
in->readMessageBegin(name, type, seqid);
|
||||
|
||||
if (type != protocol::T_CALL && type != protocol::T_ONEWAY) {
|
||||
// Unexpected message type.
|
||||
in->skip(::apache::thrift::protocol::T_STRUCT);
|
||||
in->readMessageEnd();
|
||||
in->getTransport()->readEnd();
|
||||
const std::string msg("TMultiplexedProcessor: Unexpected message type");
|
||||
::apache::thrift::TApplicationException
|
||||
x(::apache::thrift::TApplicationException::PROTOCOL_ERROR, msg);
|
||||
out->writeMessageBegin(name, ::apache::thrift::protocol::T_EXCEPTION, seqid);
|
||||
x.write(out.get());
|
||||
out->writeMessageEnd();
|
||||
out->getTransport()->writeEnd();
|
||||
out->getTransport()->flush();
|
||||
throw TException(msg);
|
||||
}
|
||||
|
||||
// Extract the service name
|
||||
|
||||
boost::tokenizer<boost::char_separator<char> > tok(name, boost::char_separator<char>(":"));
|
||||
|
||||
std::vector<std::string> tokens;
|
||||
std::copy(tok.begin(), tok.end(), std::back_inserter(tokens));
|
||||
|
||||
// A valid message should consist of two tokens: the service
|
||||
// name and the name of the method to call.
|
||||
if (tokens.size() == 2) {
|
||||
// Search for a processor associated with this service name.
|
||||
services_t::iterator it = services.find(tokens[0]);
|
||||
|
||||
if (it != services.end()) {
|
||||
shared_ptr<TProcessor> processor = it->second;
|
||||
// Let the processor registered for this service name
|
||||
// process the message.
|
||||
return processor
|
||||
->process(shared_ptr<protocol::TProtocol>(
|
||||
new protocol::StoredMessageProtocol(in, tokens[1], type, seqid)),
|
||||
out,
|
||||
connectionContext);
|
||||
} else {
|
||||
// Unknown service.
|
||||
in->skip(::apache::thrift::protocol::T_STRUCT);
|
||||
in->readMessageEnd();
|
||||
in->getTransport()->readEnd();
|
||||
|
||||
std::string msg("TMultiplexedProcessor: Unknown service: ");
|
||||
msg += tokens[0];
|
||||
::apache::thrift::TApplicationException
|
||||
x(::apache::thrift::TApplicationException::PROTOCOL_ERROR, msg);
|
||||
out->writeMessageBegin(name, ::apache::thrift::protocol::T_EXCEPTION, seqid);
|
||||
x.write(out.get());
|
||||
out->writeMessageEnd();
|
||||
out->getTransport()->writeEnd();
|
||||
out->getTransport()->flush();
|
||||
msg += ". Did you forget to call registerProcessor()?";
|
||||
throw TException(msg);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
/** Map of service processor objects, indexed by service names. */
|
||||
services_t services;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // THRIFT_TMULTIPLEXEDPROCESSOR_H_
|
317
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TBase64Utils.cpp
generated
vendored
Normal file
317
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TBase64Utils.cpp
generated
vendored
Normal file
|
@ -0,0 +1,317 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/protocol/TBase64Utils.h>
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace protocol {
|
||||
|
||||
static const uint8_t* kBase64EncodeTable
|
||||
= (const uint8_t*)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
void base64_encode(const uint8_t* in, uint32_t len, uint8_t* buf) {
|
||||
buf[0] = kBase64EncodeTable[(in[0] >> 2) & 0x3f];
|
||||
if (len == 3) {
|
||||
buf[1] = kBase64EncodeTable[((in[0] << 4) & 0x30) | ((in[1] >> 4) & 0x0f)];
|
||||
buf[2] = kBase64EncodeTable[((in[1] << 2) & 0x3c) | ((in[2] >> 6) & 0x03)];
|
||||
buf[3] = kBase64EncodeTable[in[2] & 0x3f];
|
||||
} else if (len == 2) {
|
||||
buf[1] = kBase64EncodeTable[((in[0] << 4) & 0x30) | ((in[1] >> 4) & 0x0f)];
|
||||
buf[2] = kBase64EncodeTable[(in[1] << 2) & 0x3c];
|
||||
} else { // len == 1
|
||||
buf[1] = kBase64EncodeTable[(in[0] << 4) & 0x30];
|
||||
}
|
||||
}
|
||||
|
||||
static const uint8_t kBase64DecodeTable[256] = {
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0x3e,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0x3f,
|
||||
0x34,
|
||||
0x35,
|
||||
0x36,
|
||||
0x37,
|
||||
0x38,
|
||||
0x39,
|
||||
0x3a,
|
||||
0x3b,
|
||||
0x3c,
|
||||
0x3d,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0x00,
|
||||
0x01,
|
||||
0x02,
|
||||
0x03,
|
||||
0x04,
|
||||
0x05,
|
||||
0x06,
|
||||
0x07,
|
||||
0x08,
|
||||
0x09,
|
||||
0x0a,
|
||||
0x0b,
|
||||
0x0c,
|
||||
0x0d,
|
||||
0x0e,
|
||||
0x0f,
|
||||
0x10,
|
||||
0x11,
|
||||
0x12,
|
||||
0x13,
|
||||
0x14,
|
||||
0x15,
|
||||
0x16,
|
||||
0x17,
|
||||
0x18,
|
||||
0x19,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0x1a,
|
||||
0x1b,
|
||||
0x1c,
|
||||
0x1d,
|
||||
0x1e,
|
||||
0x1f,
|
||||
0x20,
|
||||
0x21,
|
||||
0x22,
|
||||
0x23,
|
||||
0x24,
|
||||
0x25,
|
||||
0x26,
|
||||
0x27,
|
||||
0x28,
|
||||
0x29,
|
||||
0x2a,
|
||||
0x2b,
|
||||
0x2c,
|
||||
0x2d,
|
||||
0x2e,
|
||||
0x2f,
|
||||
0x30,
|
||||
0x31,
|
||||
0x32,
|
||||
0x33,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
};
|
||||
|
||||
void base64_decode(uint8_t* buf, uint32_t len) {
|
||||
buf[0] = (kBase64DecodeTable[buf[0]] << 2) | (kBase64DecodeTable[buf[1]] >> 4);
|
||||
if (len > 2) {
|
||||
buf[1] = ((kBase64DecodeTable[buf[1]] << 4) & 0xf0) | (kBase64DecodeTable[buf[2]] >> 2);
|
||||
if (len > 3) {
|
||||
buf[2] = ((kBase64DecodeTable[buf[2]] << 6) & 0xc0) | (kBase64DecodeTable[buf[3]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::protocol
|
45
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TBase64Utils.h
generated
vendored
Normal file
45
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TBase64Utils.h
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_PROTOCOL_TBASE64UTILS_H_
|
||||
#define _THRIFT_PROTOCOL_TBASE64UTILS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace protocol {
|
||||
|
||||
// in must be at least len bytes
|
||||
// len must be 1, 2, or 3
|
||||
// buf must be a buffer of at least 4 bytes and may not overlap in
|
||||
// the data is not padded with '='; the caller can do this if desired
|
||||
void base64_encode(const uint8_t* in, uint32_t len, uint8_t* buf);
|
||||
|
||||
// buf must be a buffer of at least 4 bytes and contain base64 encoded values
|
||||
// buf will be changed to contain output bytes
|
||||
// len is number of bytes to consume from input (must be 2, 3, or 4)
|
||||
// no '=' padding should be included in the input
|
||||
void base64_decode(uint8_t* buf, uint32_t len);
|
||||
}
|
||||
}
|
||||
} // apache::thrift::protocol
|
||||
|
||||
#endif // #define _THRIFT_PROTOCOL_TBASE64UTILS_H_
|
250
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TBinaryProtocol.h
generated
vendored
Normal file
250
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TBinaryProtocol.h
generated
vendored
Normal file
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_PROTOCOL_TBINARYPROTOCOL_H_
|
||||
#define _THRIFT_PROTOCOL_TBINARYPROTOCOL_H_ 1
|
||||
|
||||
#include <thrift/protocol/TProtocol.h>
|
||||
#include <thrift/protocol/TVirtualProtocol.h>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace protocol {
|
||||
|
||||
/**
|
||||
* The default binary protocol for thrift. Writes all data in a very basic
|
||||
* binary format, essentially just spitting out the raw bytes.
|
||||
*
|
||||
*/
|
||||
template <class Transport_, class ByteOrder_ = TNetworkBigEndian>
|
||||
class TBinaryProtocolT : public TVirtualProtocol<TBinaryProtocolT<Transport_, ByteOrder_> > {
|
||||
public:
|
||||
static const int32_t VERSION_MASK = ((int32_t)0xffff0000);
|
||||
static const int32_t VERSION_1 = ((int32_t)0x80010000);
|
||||
// VERSION_2 (0x80020000) was taken by TDenseProtocol (which has since been removed)
|
||||
|
||||
TBinaryProtocolT(boost::shared_ptr<Transport_> trans)
|
||||
: TVirtualProtocol<TBinaryProtocolT<Transport_, ByteOrder_> >(trans),
|
||||
trans_(trans.get()),
|
||||
string_limit_(0),
|
||||
container_limit_(0),
|
||||
strict_read_(false),
|
||||
strict_write_(true) {}
|
||||
|
||||
TBinaryProtocolT(boost::shared_ptr<Transport_> trans,
|
||||
int32_t string_limit,
|
||||
int32_t container_limit,
|
||||
bool strict_read,
|
||||
bool strict_write)
|
||||
: TVirtualProtocol<TBinaryProtocolT<Transport_, ByteOrder_> >(trans),
|
||||
trans_(trans.get()),
|
||||
string_limit_(string_limit),
|
||||
container_limit_(container_limit),
|
||||
strict_read_(strict_read),
|
||||
strict_write_(strict_write) {}
|
||||
|
||||
void setStringSizeLimit(int32_t string_limit) { string_limit_ = string_limit; }
|
||||
|
||||
void setContainerSizeLimit(int32_t container_limit) { container_limit_ = container_limit; }
|
||||
|
||||
void setStrict(bool strict_read, bool strict_write) {
|
||||
strict_read_ = strict_read;
|
||||
strict_write_ = strict_write;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writing functions.
|
||||
*/
|
||||
|
||||
/*ol*/ uint32_t writeMessageBegin(const std::string& name,
|
||||
const TMessageType messageType,
|
||||
const int32_t seqid);
|
||||
|
||||
/*ol*/ uint32_t writeMessageEnd();
|
||||
|
||||
inline uint32_t writeStructBegin(const char* name);
|
||||
|
||||
inline uint32_t writeStructEnd();
|
||||
|
||||
inline uint32_t writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId);
|
||||
|
||||
inline uint32_t writeFieldEnd();
|
||||
|
||||
inline uint32_t writeFieldStop();
|
||||
|
||||
inline uint32_t writeMapBegin(const TType keyType, const TType valType, const uint32_t size);
|
||||
|
||||
inline uint32_t writeMapEnd();
|
||||
|
||||
inline uint32_t writeListBegin(const TType elemType, const uint32_t size);
|
||||
|
||||
inline uint32_t writeListEnd();
|
||||
|
||||
inline uint32_t writeSetBegin(const TType elemType, const uint32_t size);
|
||||
|
||||
inline uint32_t writeSetEnd();
|
||||
|
||||
inline uint32_t writeBool(const bool value);
|
||||
|
||||
inline uint32_t writeByte(const int8_t byte);
|
||||
|
||||
inline uint32_t writeI16(const int16_t i16);
|
||||
|
||||
inline uint32_t writeI32(const int32_t i32);
|
||||
|
||||
inline uint32_t writeI64(const int64_t i64);
|
||||
|
||||
inline uint32_t writeDouble(const double dub);
|
||||
|
||||
template <typename StrType>
|
||||
inline uint32_t writeString(const StrType& str);
|
||||
|
||||
inline uint32_t writeBinary(const std::string& str);
|
||||
|
||||
/**
|
||||
* Reading functions
|
||||
*/
|
||||
|
||||
/*ol*/ uint32_t readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqid);
|
||||
|
||||
/*ol*/ uint32_t readMessageEnd();
|
||||
|
||||
inline uint32_t readStructBegin(std::string& name);
|
||||
|
||||
inline uint32_t readStructEnd();
|
||||
|
||||
inline uint32_t readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId);
|
||||
|
||||
inline uint32_t readFieldEnd();
|
||||
|
||||
inline uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size);
|
||||
|
||||
inline uint32_t readMapEnd();
|
||||
|
||||
inline uint32_t readListBegin(TType& elemType, uint32_t& size);
|
||||
|
||||
inline uint32_t readListEnd();
|
||||
|
||||
inline uint32_t readSetBegin(TType& elemType, uint32_t& size);
|
||||
|
||||
inline uint32_t readSetEnd();
|
||||
|
||||
inline uint32_t readBool(bool& value);
|
||||
// Provide the default readBool() implementation for std::vector<bool>
|
||||
using TVirtualProtocol<TBinaryProtocolT<Transport_, ByteOrder_> >::readBool;
|
||||
|
||||
inline uint32_t readByte(int8_t& byte);
|
||||
|
||||
inline uint32_t readI16(int16_t& i16);
|
||||
|
||||
inline uint32_t readI32(int32_t& i32);
|
||||
|
||||
inline uint32_t readI64(int64_t& i64);
|
||||
|
||||
inline uint32_t readDouble(double& dub);
|
||||
|
||||
template <typename StrType>
|
||||
inline uint32_t readString(StrType& str);
|
||||
|
||||
inline uint32_t readBinary(std::string& str);
|
||||
|
||||
protected:
|
||||
template <typename StrType>
|
||||
uint32_t readStringBody(StrType& str, int32_t sz);
|
||||
|
||||
Transport_* trans_;
|
||||
|
||||
int32_t string_limit_;
|
||||
int32_t container_limit_;
|
||||
|
||||
// Enforce presence of version identifier
|
||||
bool strict_read_;
|
||||
bool strict_write_;
|
||||
};
|
||||
|
||||
typedef TBinaryProtocolT<TTransport> TBinaryProtocol;
|
||||
typedef TBinaryProtocolT<TTransport, TNetworkLittleEndian> TLEBinaryProtocol;
|
||||
|
||||
/**
|
||||
* Constructs binary protocol handlers
|
||||
*/
|
||||
template <class Transport_, class ByteOrder_ = TNetworkBigEndian>
|
||||
class TBinaryProtocolFactoryT : public TProtocolFactory {
|
||||
public:
|
||||
TBinaryProtocolFactoryT()
|
||||
: string_limit_(0), container_limit_(0), strict_read_(false), strict_write_(true) {}
|
||||
|
||||
TBinaryProtocolFactoryT(int32_t string_limit,
|
||||
int32_t container_limit,
|
||||
bool strict_read,
|
||||
bool strict_write)
|
||||
: string_limit_(string_limit),
|
||||
container_limit_(container_limit),
|
||||
strict_read_(strict_read),
|
||||
strict_write_(strict_write) {}
|
||||
|
||||
virtual ~TBinaryProtocolFactoryT() {}
|
||||
|
||||
void setStringSizeLimit(int32_t string_limit) { string_limit_ = string_limit; }
|
||||
|
||||
void setContainerSizeLimit(int32_t container_limit) { container_limit_ = container_limit; }
|
||||
|
||||
void setStrict(bool strict_read, bool strict_write) {
|
||||
strict_read_ = strict_read;
|
||||
strict_write_ = strict_write;
|
||||
}
|
||||
|
||||
boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) {
|
||||
boost::shared_ptr<Transport_> specific_trans = boost::dynamic_pointer_cast<Transport_>(trans);
|
||||
TProtocol* prot;
|
||||
if (specific_trans) {
|
||||
prot = new TBinaryProtocolT<Transport_, ByteOrder_>(specific_trans,
|
||||
string_limit_,
|
||||
container_limit_,
|
||||
strict_read_,
|
||||
strict_write_);
|
||||
} else {
|
||||
prot = new TBinaryProtocolT<TTransport, ByteOrder_>(trans,
|
||||
string_limit_,
|
||||
container_limit_,
|
||||
strict_read_,
|
||||
strict_write_);
|
||||
}
|
||||
|
||||
return boost::shared_ptr<TProtocol>(prot);
|
||||
}
|
||||
|
||||
private:
|
||||
int32_t string_limit_;
|
||||
int32_t container_limit_;
|
||||
bool strict_read_;
|
||||
bool strict_write_;
|
||||
};
|
||||
|
||||
typedef TBinaryProtocolFactoryT<TTransport> TBinaryProtocolFactory;
|
||||
typedef TBinaryProtocolFactoryT<TTransport, TNetworkLittleEndian> TLEBinaryProtocolFactory;
|
||||
}
|
||||
}
|
||||
} // apache::thrift::protocol
|
||||
|
||||
#include <thrift/protocol/TBinaryProtocol.tcc>
|
||||
|
||||
#endif // #ifndef _THRIFT_PROTOCOL_TBINARYPROTOCOL_H_
|
454
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TBinaryProtocol.tcc
generated
vendored
Normal file
454
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TBinaryProtocol.tcc
generated
vendored
Normal file
|
@ -0,0 +1,454 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_PROTOCOL_TBINARYPROTOCOL_TCC_
|
||||
#define _THRIFT_PROTOCOL_TBINARYPROTOCOL_TCC_ 1
|
||||
|
||||
#include <thrift/protocol/TBinaryProtocol.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace protocol {
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeMessageBegin(const std::string& name,
|
||||
const TMessageType messageType,
|
||||
const int32_t seqid) {
|
||||
if (this->strict_write_) {
|
||||
int32_t version = (VERSION_1) | ((int32_t)messageType);
|
||||
uint32_t wsize = 0;
|
||||
wsize += writeI32(version);
|
||||
wsize += writeString(name);
|
||||
wsize += writeI32(seqid);
|
||||
return wsize;
|
||||
} else {
|
||||
uint32_t wsize = 0;
|
||||
wsize += writeString(name);
|
||||
wsize += writeByte((int8_t)messageType);
|
||||
wsize += writeI32(seqid);
|
||||
return wsize;
|
||||
}
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeMessageEnd() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeStructBegin(const char* name) {
|
||||
(void)name;
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeStructEnd() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeFieldBegin(const char* name,
|
||||
const TType fieldType,
|
||||
const int16_t fieldId) {
|
||||
(void)name;
|
||||
uint32_t wsize = 0;
|
||||
wsize += writeByte((int8_t)fieldType);
|
||||
wsize += writeI16(fieldId);
|
||||
return wsize;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeFieldEnd() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeFieldStop() {
|
||||
return writeByte((int8_t)T_STOP);
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeMapBegin(const TType keyType,
|
||||
const TType valType,
|
||||
const uint32_t size) {
|
||||
uint32_t wsize = 0;
|
||||
wsize += writeByte((int8_t)keyType);
|
||||
wsize += writeByte((int8_t)valType);
|
||||
wsize += writeI32((int32_t)size);
|
||||
return wsize;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeMapEnd() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeListBegin(const TType elemType,
|
||||
const uint32_t size) {
|
||||
uint32_t wsize = 0;
|
||||
wsize += writeByte((int8_t)elemType);
|
||||
wsize += writeI32((int32_t)size);
|
||||
return wsize;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeListEnd() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeSetBegin(const TType elemType,
|
||||
const uint32_t size) {
|
||||
uint32_t wsize = 0;
|
||||
wsize += writeByte((int8_t)elemType);
|
||||
wsize += writeI32((int32_t)size);
|
||||
return wsize;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeSetEnd() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeBool(const bool value) {
|
||||
uint8_t tmp = value ? 1 : 0;
|
||||
this->trans_->write(&tmp, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeByte(const int8_t byte) {
|
||||
this->trans_->write((uint8_t*)&byte, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeI16(const int16_t i16) {
|
||||
int16_t net = (int16_t)ByteOrder_::toWire16(i16);
|
||||
this->trans_->write((uint8_t*)&net, 2);
|
||||
return 2;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeI32(const int32_t i32) {
|
||||
int32_t net = (int32_t)ByteOrder_::toWire32(i32);
|
||||
this->trans_->write((uint8_t*)&net, 4);
|
||||
return 4;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeI64(const int64_t i64) {
|
||||
int64_t net = (int64_t)ByteOrder_::toWire64(i64);
|
||||
this->trans_->write((uint8_t*)&net, 8);
|
||||
return 8;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeDouble(const double dub) {
|
||||
BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
|
||||
BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
|
||||
|
||||
uint64_t bits = bitwise_cast<uint64_t>(dub);
|
||||
bits = ByteOrder_::toWire64(bits);
|
||||
this->trans_->write((uint8_t*)&bits, 8);
|
||||
return 8;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
template <typename StrType>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeString(const StrType& str) {
|
||||
if (str.size() > static_cast<size_t>((std::numeric_limits<int32_t>::max)()))
|
||||
throw TProtocolException(TProtocolException::SIZE_LIMIT);
|
||||
uint32_t size = static_cast<uint32_t>(str.size());
|
||||
uint32_t result = writeI32((int32_t)size);
|
||||
if (size > 0) {
|
||||
this->trans_->write((uint8_t*)str.data(), size);
|
||||
}
|
||||
return result + size;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeBinary(const std::string& str) {
|
||||
return TBinaryProtocolT<Transport_, ByteOrder_>::writeString(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reading functions
|
||||
*/
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readMessageBegin(std::string& name,
|
||||
TMessageType& messageType,
|
||||
int32_t& seqid) {
|
||||
uint32_t result = 0;
|
||||
int32_t sz;
|
||||
result += readI32(sz);
|
||||
|
||||
if (sz < 0) {
|
||||
// Check for correct version number
|
||||
int32_t version = sz & VERSION_MASK;
|
||||
if (version != VERSION_1) {
|
||||
throw TProtocolException(TProtocolException::BAD_VERSION, "Bad version identifier");
|
||||
}
|
||||
messageType = (TMessageType)(sz & 0x000000ff);
|
||||
result += readString(name);
|
||||
result += readI32(seqid);
|
||||
} else {
|
||||
if (this->strict_read_) {
|
||||
throw TProtocolException(TProtocolException::BAD_VERSION,
|
||||
"No version identifier... old protocol client in strict mode?");
|
||||
} else {
|
||||
// Handle pre-versioned input
|
||||
int8_t type;
|
||||
result += readStringBody(name, sz);
|
||||
result += readByte(type);
|
||||
messageType = (TMessageType)type;
|
||||
result += readI32(seqid);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readMessageEnd() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readStructBegin(std::string& name) {
|
||||
name = "";
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readStructEnd() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readFieldBegin(std::string& name,
|
||||
TType& fieldType,
|
||||
int16_t& fieldId) {
|
||||
(void)name;
|
||||
uint32_t result = 0;
|
||||
int8_t type;
|
||||
result += readByte(type);
|
||||
fieldType = (TType)type;
|
||||
if (fieldType == T_STOP) {
|
||||
fieldId = 0;
|
||||
return result;
|
||||
}
|
||||
result += readI16(fieldId);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readFieldEnd() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readMapBegin(TType& keyType,
|
||||
TType& valType,
|
||||
uint32_t& size) {
|
||||
int8_t k, v;
|
||||
uint32_t result = 0;
|
||||
int32_t sizei;
|
||||
result += readByte(k);
|
||||
keyType = (TType)k;
|
||||
result += readByte(v);
|
||||
valType = (TType)v;
|
||||
result += readI32(sizei);
|
||||
if (sizei < 0) {
|
||||
throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
|
||||
} else if (this->container_limit_ && sizei > this->container_limit_) {
|
||||
throw TProtocolException(TProtocolException::SIZE_LIMIT);
|
||||
}
|
||||
size = (uint32_t)sizei;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readMapEnd() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readListBegin(TType& elemType, uint32_t& size) {
|
||||
int8_t e;
|
||||
uint32_t result = 0;
|
||||
int32_t sizei;
|
||||
result += readByte(e);
|
||||
elemType = (TType)e;
|
||||
result += readI32(sizei);
|
||||
if (sizei < 0) {
|
||||
throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
|
||||
} else if (this->container_limit_ && sizei > this->container_limit_) {
|
||||
throw TProtocolException(TProtocolException::SIZE_LIMIT);
|
||||
}
|
||||
size = (uint32_t)sizei;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readListEnd() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readSetBegin(TType& elemType, uint32_t& size) {
|
||||
int8_t e;
|
||||
uint32_t result = 0;
|
||||
int32_t sizei;
|
||||
result += readByte(e);
|
||||
elemType = (TType)e;
|
||||
result += readI32(sizei);
|
||||
if (sizei < 0) {
|
||||
throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
|
||||
} else if (this->container_limit_ && sizei > this->container_limit_) {
|
||||
throw TProtocolException(TProtocolException::SIZE_LIMIT);
|
||||
}
|
||||
size = (uint32_t)sizei;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readSetEnd() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readBool(bool& value) {
|
||||
uint8_t b[1];
|
||||
this->trans_->readAll(b, 1);
|
||||
value = *(int8_t*)b != 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readByte(int8_t& byte) {
|
||||
uint8_t b[1];
|
||||
this->trans_->readAll(b, 1);
|
||||
byte = *(int8_t*)b;
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readI16(int16_t& i16) {
|
||||
union bytes {
|
||||
uint8_t b[2];
|
||||
int16_t all;
|
||||
} theBytes;
|
||||
this->trans_->readAll(theBytes.b, 2);
|
||||
i16 = (int16_t)ByteOrder_::fromWire16(theBytes.all);
|
||||
return 2;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readI32(int32_t& i32) {
|
||||
union bytes {
|
||||
uint8_t b[4];
|
||||
int32_t all;
|
||||
} theBytes;
|
||||
this->trans_->readAll(theBytes.b, 4);
|
||||
i32 = (int32_t)ByteOrder_::fromWire32(theBytes.all);
|
||||
return 4;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readI64(int64_t& i64) {
|
||||
union bytes {
|
||||
uint8_t b[8];
|
||||
int64_t all;
|
||||
} theBytes;
|
||||
this->trans_->readAll(theBytes.b, 8);
|
||||
i64 = (int64_t)ByteOrder_::fromWire64(theBytes.all);
|
||||
return 8;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readDouble(double& dub) {
|
||||
BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
|
||||
BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
|
||||
|
||||
union bytes {
|
||||
uint8_t b[8];
|
||||
uint64_t all;
|
||||
} theBytes;
|
||||
this->trans_->readAll(theBytes.b, 8);
|
||||
theBytes.all = ByteOrder_::fromWire64(theBytes.all);
|
||||
dub = bitwise_cast<double>(theBytes.all);
|
||||
return 8;
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
template <typename StrType>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readString(StrType& str) {
|
||||
uint32_t result;
|
||||
int32_t size;
|
||||
result = readI32(size);
|
||||
return result + readStringBody(str, size);
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readBinary(std::string& str) {
|
||||
return TBinaryProtocolT<Transport_, ByteOrder_>::readString(str);
|
||||
}
|
||||
|
||||
template <class Transport_, class ByteOrder_>
|
||||
template <typename StrType>
|
||||
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readStringBody(StrType& str, int32_t size) {
|
||||
uint32_t result = 0;
|
||||
|
||||
// Catch error cases
|
||||
if (size < 0) {
|
||||
throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
|
||||
}
|
||||
if (this->string_limit_ > 0 && size > this->string_limit_) {
|
||||
throw TProtocolException(TProtocolException::SIZE_LIMIT);
|
||||
}
|
||||
|
||||
// Catch empty string case
|
||||
if (size == 0) {
|
||||
str.clear();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Try to borrow first
|
||||
const uint8_t* borrow_buf;
|
||||
uint32_t got = size;
|
||||
if ((borrow_buf = this->trans_->borrow(NULL, &got))) {
|
||||
str.assign((const char*)borrow_buf, size);
|
||||
this->trans_->consume(size);
|
||||
return size;
|
||||
}
|
||||
|
||||
str.resize(size);
|
||||
this->trans_->readAll(reinterpret_cast<uint8_t*>(&str[0]), size);
|
||||
return (uint32_t)size;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::protocol
|
||||
|
||||
#endif // #ifndef _THRIFT_PROTOCOL_TBINARYPROTOCOL_TCC_
|
266
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TCompactProtocol.h
generated
vendored
Normal file
266
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TCompactProtocol.h
generated
vendored
Normal file
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_PROTOCOL_TCOMPACTPROTOCOL_H_
|
||||
#define _THRIFT_PROTOCOL_TCOMPACTPROTOCOL_H_ 1
|
||||
|
||||
#include <thrift/protocol/TVirtualProtocol.h>
|
||||
|
||||
#include <stack>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace protocol {
|
||||
|
||||
/**
|
||||
* C++ Implementation of the Compact Protocol as described in THRIFT-110
|
||||
*/
|
||||
template <class Transport_>
|
||||
class TCompactProtocolT : public TVirtualProtocol<TCompactProtocolT<Transport_> > {
|
||||
public:
|
||||
static const int8_t PROTOCOL_ID = (int8_t)0x82u;
|
||||
static const int8_t VERSION_N = 1;
|
||||
static const int8_t VERSION_MASK = 0x1f; // 0001 1111
|
||||
|
||||
protected:
|
||||
static const int8_t TYPE_MASK = (int8_t)0xE0u; // 1110 0000
|
||||
static const int8_t TYPE_BITS = 0x07; // 0000 0111
|
||||
static const int32_t TYPE_SHIFT_AMOUNT = 5;
|
||||
|
||||
Transport_* trans_;
|
||||
|
||||
/**
|
||||
* (Writing) If we encounter a boolean field begin, save the TField here
|
||||
* so it can have the value incorporated.
|
||||
*/
|
||||
struct {
|
||||
const char* name;
|
||||
TType fieldType;
|
||||
int16_t fieldId;
|
||||
} booleanField_;
|
||||
|
||||
/**
|
||||
* (Reading) If we read a field header, and it's a boolean field, save
|
||||
* the boolean value here so that readBool can use it.
|
||||
*/
|
||||
struct {
|
||||
bool hasBoolValue;
|
||||
bool boolValue;
|
||||
} boolValue_;
|
||||
|
||||
/**
|
||||
* Used to keep track of the last field for the current and previous structs,
|
||||
* so we can do the delta stuff.
|
||||
*/
|
||||
|
||||
std::stack<int16_t> lastField_;
|
||||
int16_t lastFieldId_;
|
||||
|
||||
public:
|
||||
TCompactProtocolT(boost::shared_ptr<Transport_> trans)
|
||||
: TVirtualProtocol<TCompactProtocolT<Transport_> >(trans),
|
||||
trans_(trans.get()),
|
||||
lastFieldId_(0),
|
||||
string_limit_(0),
|
||||
string_buf_(NULL),
|
||||
string_buf_size_(0),
|
||||
container_limit_(0) {
|
||||
booleanField_.name = NULL;
|
||||
boolValue_.hasBoolValue = false;
|
||||
}
|
||||
|
||||
TCompactProtocolT(boost::shared_ptr<Transport_> trans,
|
||||
int32_t string_limit,
|
||||
int32_t container_limit)
|
||||
: TVirtualProtocol<TCompactProtocolT<Transport_> >(trans),
|
||||
trans_(trans.get()),
|
||||
lastFieldId_(0),
|
||||
string_limit_(string_limit),
|
||||
string_buf_(NULL),
|
||||
string_buf_size_(0),
|
||||
container_limit_(container_limit) {
|
||||
booleanField_.name = NULL;
|
||||
boolValue_.hasBoolValue = false;
|
||||
}
|
||||
|
||||
~TCompactProtocolT() { free(string_buf_); }
|
||||
|
||||
/**
|
||||
* Writing functions
|
||||
*/
|
||||
|
||||
virtual uint32_t writeMessageBegin(const std::string& name,
|
||||
const TMessageType messageType,
|
||||
const int32_t seqid);
|
||||
|
||||
uint32_t writeStructBegin(const char* name);
|
||||
|
||||
uint32_t writeStructEnd();
|
||||
|
||||
uint32_t writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId);
|
||||
|
||||
uint32_t writeFieldStop();
|
||||
|
||||
uint32_t writeListBegin(const TType elemType, const uint32_t size);
|
||||
|
||||
uint32_t writeSetBegin(const TType elemType, const uint32_t size);
|
||||
|
||||
virtual uint32_t writeMapBegin(const TType keyType, const TType valType, const uint32_t size);
|
||||
|
||||
uint32_t writeBool(const bool value);
|
||||
|
||||
uint32_t writeByte(const int8_t byte);
|
||||
|
||||
uint32_t writeI16(const int16_t i16);
|
||||
|
||||
uint32_t writeI32(const int32_t i32);
|
||||
|
||||
uint32_t writeI64(const int64_t i64);
|
||||
|
||||
uint32_t writeDouble(const double dub);
|
||||
|
||||
uint32_t writeString(const std::string& str);
|
||||
|
||||
uint32_t writeBinary(const std::string& str);
|
||||
|
||||
/**
|
||||
* These methods are called by structs, but don't actually have any wired
|
||||
* output or purpose
|
||||
*/
|
||||
virtual uint32_t writeMessageEnd() { return 0; }
|
||||
uint32_t writeMapEnd() { return 0; }
|
||||
uint32_t writeListEnd() { return 0; }
|
||||
uint32_t writeSetEnd() { return 0; }
|
||||
uint32_t writeFieldEnd() { return 0; }
|
||||
|
||||
protected:
|
||||
int32_t writeFieldBeginInternal(const char* name,
|
||||
const TType fieldType,
|
||||
const int16_t fieldId,
|
||||
int8_t typeOverride);
|
||||
uint32_t writeCollectionBegin(const TType elemType, int32_t size);
|
||||
uint32_t writeVarint32(uint32_t n);
|
||||
uint32_t writeVarint64(uint64_t n);
|
||||
uint64_t i64ToZigzag(const int64_t l);
|
||||
uint32_t i32ToZigzag(const int32_t n);
|
||||
inline int8_t getCompactType(const TType ttype);
|
||||
|
||||
public:
|
||||
uint32_t readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqid);
|
||||
|
||||
uint32_t readStructBegin(std::string& name);
|
||||
|
||||
uint32_t readStructEnd();
|
||||
|
||||
uint32_t readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId);
|
||||
|
||||
uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size);
|
||||
|
||||
uint32_t readListBegin(TType& elemType, uint32_t& size);
|
||||
|
||||
uint32_t readSetBegin(TType& elemType, uint32_t& size);
|
||||
|
||||
uint32_t readBool(bool& value);
|
||||
// Provide the default readBool() implementation for std::vector<bool>
|
||||
using TVirtualProtocol<TCompactProtocolT<Transport_> >::readBool;
|
||||
|
||||
uint32_t readByte(int8_t& byte);
|
||||
|
||||
uint32_t readI16(int16_t& i16);
|
||||
|
||||
uint32_t readI32(int32_t& i32);
|
||||
|
||||
uint32_t readI64(int64_t& i64);
|
||||
|
||||
uint32_t readDouble(double& dub);
|
||||
|
||||
uint32_t readString(std::string& str);
|
||||
|
||||
uint32_t readBinary(std::string& str);
|
||||
|
||||
/*
|
||||
*These methods are here for the struct to call, but don't have any wire
|
||||
* encoding.
|
||||
*/
|
||||
uint32_t readMessageEnd() { return 0; }
|
||||
uint32_t readFieldEnd() { return 0; }
|
||||
uint32_t readMapEnd() { return 0; }
|
||||
uint32_t readListEnd() { return 0; }
|
||||
uint32_t readSetEnd() { return 0; }
|
||||
|
||||
protected:
|
||||
uint32_t readVarint32(int32_t& i32);
|
||||
uint32_t readVarint64(int64_t& i64);
|
||||
int32_t zigzagToI32(uint32_t n);
|
||||
int64_t zigzagToI64(uint64_t n);
|
||||
TType getTType(int8_t type);
|
||||
|
||||
// Buffer for reading strings, save for the lifetime of the protocol to
|
||||
// avoid memory churn allocating memory on every string read
|
||||
int32_t string_limit_;
|
||||
uint8_t* string_buf_;
|
||||
int32_t string_buf_size_;
|
||||
int32_t container_limit_;
|
||||
};
|
||||
|
||||
typedef TCompactProtocolT<TTransport> TCompactProtocol;
|
||||
|
||||
/**
|
||||
* Constructs compact protocol handlers
|
||||
*/
|
||||
template <class Transport_>
|
||||
class TCompactProtocolFactoryT : public TProtocolFactory {
|
||||
public:
|
||||
TCompactProtocolFactoryT() : string_limit_(0), container_limit_(0) {}
|
||||
|
||||
TCompactProtocolFactoryT(int32_t string_limit, int32_t container_limit)
|
||||
: string_limit_(string_limit), container_limit_(container_limit) {}
|
||||
|
||||
virtual ~TCompactProtocolFactoryT() {}
|
||||
|
||||
void setStringSizeLimit(int32_t string_limit) { string_limit_ = string_limit; }
|
||||
|
||||
void setContainerSizeLimit(int32_t container_limit) { container_limit_ = container_limit; }
|
||||
|
||||
boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) {
|
||||
boost::shared_ptr<Transport_> specific_trans = boost::dynamic_pointer_cast<Transport_>(trans);
|
||||
TProtocol* prot;
|
||||
if (specific_trans) {
|
||||
prot = new TCompactProtocolT<Transport_>(specific_trans, string_limit_, container_limit_);
|
||||
} else {
|
||||
prot = new TCompactProtocol(trans, string_limit_, container_limit_);
|
||||
}
|
||||
|
||||
return boost::shared_ptr<TProtocol>(prot);
|
||||
}
|
||||
|
||||
private:
|
||||
int32_t string_limit_;
|
||||
int32_t container_limit_;
|
||||
};
|
||||
|
||||
typedef TCompactProtocolFactoryT<TTransport> TCompactProtocolFactory;
|
||||
}
|
||||
}
|
||||
} // apache::thrift::protocol
|
||||
|
||||
#include <thrift/protocol/TCompactProtocol.tcc>
|
||||
|
||||
#endif
|
826
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc
generated
vendored
Normal file
826
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc
generated
vendored
Normal file
|
@ -0,0 +1,826 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
#ifndef _THRIFT_PROTOCOL_TCOMPACTPROTOCOL_TCC_
|
||||
#define _THRIFT_PROTOCOL_TCOMPACTPROTOCOL_TCC_ 1
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "thrift/config.h"
|
||||
|
||||
/*
|
||||
* TCompactProtocol::i*ToZigzag depend on the fact that the right shift
|
||||
* operator on a signed integer is an arithmetic (sign-extending) shift.
|
||||
* If this is not the case, the current implementation will not work.
|
||||
* If anyone encounters this error, we can try to figure out the best
|
||||
* way to implement an arithmetic right shift on their platform.
|
||||
*/
|
||||
#if !defined(SIGNED_RIGHT_SHIFT_IS) || !defined(ARITHMETIC_RIGHT_SHIFT)
|
||||
# error "Unable to determine the behavior of a signed right shift"
|
||||
#endif
|
||||
#if SIGNED_RIGHT_SHIFT_IS != ARITHMETIC_RIGHT_SHIFT
|
||||
# error "TCompactProtocol currently only works if a signed right shift is arithmetic"
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define UNLIKELY(val) (__builtin_expect((val), 0))
|
||||
#else
|
||||
#define UNLIKELY(val) (val)
|
||||
#endif
|
||||
|
||||
namespace apache { namespace thrift { namespace protocol {
|
||||
|
||||
namespace detail { namespace compact {
|
||||
|
||||
enum Types {
|
||||
CT_STOP = 0x00,
|
||||
CT_BOOLEAN_TRUE = 0x01,
|
||||
CT_BOOLEAN_FALSE = 0x02,
|
||||
CT_BYTE = 0x03,
|
||||
CT_I16 = 0x04,
|
||||
CT_I32 = 0x05,
|
||||
CT_I64 = 0x06,
|
||||
CT_DOUBLE = 0x07,
|
||||
CT_BINARY = 0x08,
|
||||
CT_LIST = 0x09,
|
||||
CT_SET = 0x0A,
|
||||
CT_MAP = 0x0B,
|
||||
CT_STRUCT = 0x0C
|
||||
};
|
||||
|
||||
const int8_t TTypeToCType[16] = {
|
||||
CT_STOP, // T_STOP
|
||||
0, // unused
|
||||
CT_BOOLEAN_TRUE, // T_BOOL
|
||||
CT_BYTE, // T_BYTE
|
||||
CT_DOUBLE, // T_DOUBLE
|
||||
0, // unused
|
||||
CT_I16, // T_I16
|
||||
0, // unused
|
||||
CT_I32, // T_I32
|
||||
0, // unused
|
||||
CT_I64, // T_I64
|
||||
CT_BINARY, // T_STRING
|
||||
CT_STRUCT, // T_STRUCT
|
||||
CT_MAP, // T_MAP
|
||||
CT_SET, // T_SET
|
||||
CT_LIST, // T_LIST
|
||||
};
|
||||
|
||||
}} // end detail::compact namespace
|
||||
|
||||
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::writeMessageBegin(
|
||||
const std::string& name,
|
||||
const TMessageType messageType,
|
||||
const int32_t seqid) {
|
||||
uint32_t wsize = 0;
|
||||
wsize += writeByte(PROTOCOL_ID);
|
||||
wsize += writeByte((VERSION_N & VERSION_MASK) | (((int32_t)messageType << TYPE_SHIFT_AMOUNT) & TYPE_MASK));
|
||||
wsize += writeVarint32(seqid);
|
||||
wsize += writeString(name);
|
||||
return wsize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a field header containing the field id and field type. If the
|
||||
* difference between the current field id and the last one is small (< 15),
|
||||
* then the field id will be encoded in the 4 MSB as a delta. Otherwise, the
|
||||
* field id will follow the type header as a zigzag varint.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::writeFieldBegin(const char* name,
|
||||
const TType fieldType,
|
||||
const int16_t fieldId) {
|
||||
if (fieldType == T_BOOL) {
|
||||
booleanField_.name = name;
|
||||
booleanField_.fieldType = fieldType;
|
||||
booleanField_.fieldId = fieldId;
|
||||
} else {
|
||||
return writeFieldBeginInternal(name, fieldType, fieldId, -1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the STOP symbol so we know there are no more fields in this struct.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::writeFieldStop() {
|
||||
return writeByte(T_STOP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a struct begin. This doesn't actually put anything on the wire. We
|
||||
* use it as an opportunity to put special placeholder markers on the field
|
||||
* stack so we can get the field id deltas correct.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::writeStructBegin(const char* name) {
|
||||
(void) name;
|
||||
lastField_.push(lastFieldId_);
|
||||
lastFieldId_ = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a struct end. This doesn't actually put anything on the wire. We use
|
||||
* this as an opportunity to pop the last field from the current struct off
|
||||
* of the field stack.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::writeStructEnd() {
|
||||
lastFieldId_ = lastField_.top();
|
||||
lastField_.pop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a List header.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::writeListBegin(const TType elemType,
|
||||
const uint32_t size) {
|
||||
return writeCollectionBegin(elemType, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a set header.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::writeSetBegin(const TType elemType,
|
||||
const uint32_t size) {
|
||||
return writeCollectionBegin(elemType, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a map header. If the map is empty, omit the key and value type
|
||||
* headers, as we don't need any additional information to skip it.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::writeMapBegin(const TType keyType,
|
||||
const TType valType,
|
||||
const uint32_t size) {
|
||||
uint32_t wsize = 0;
|
||||
|
||||
if (size == 0) {
|
||||
wsize += writeByte(0);
|
||||
} else {
|
||||
wsize += writeVarint32(size);
|
||||
wsize += writeByte(getCompactType(keyType) << 4 | getCompactType(valType));
|
||||
}
|
||||
return wsize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a boolean value. Potentially, this could be a boolean field, in
|
||||
* which case the field header info isn't written yet. If so, decide what the
|
||||
* right type header is for the value and then write the field header.
|
||||
* Otherwise, write a single byte.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::writeBool(const bool value) {
|
||||
uint32_t wsize = 0;
|
||||
|
||||
if (booleanField_.name != NULL) {
|
||||
// we haven't written the field header yet
|
||||
wsize
|
||||
+= writeFieldBeginInternal(booleanField_.name,
|
||||
booleanField_.fieldType,
|
||||
booleanField_.fieldId,
|
||||
static_cast<int8_t>(value
|
||||
? detail::compact::CT_BOOLEAN_TRUE
|
||||
: detail::compact::CT_BOOLEAN_FALSE));
|
||||
booleanField_.name = NULL;
|
||||
} else {
|
||||
// we're not part of a field, so just write the value
|
||||
wsize
|
||||
+= writeByte(static_cast<int8_t>(value
|
||||
? detail::compact::CT_BOOLEAN_TRUE
|
||||
: detail::compact::CT_BOOLEAN_FALSE));
|
||||
}
|
||||
return wsize;
|
||||
}
|
||||
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::writeByte(const int8_t byte) {
|
||||
trans_->write((uint8_t*)&byte, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an i16 as a zigzag varint.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::writeI16(const int16_t i16) {
|
||||
return writeVarint32(i32ToZigzag(i16));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an i32 as a zigzag varint.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::writeI32(const int32_t i32) {
|
||||
return writeVarint32(i32ToZigzag(i32));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an i64 as a zigzag varint.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::writeI64(const int64_t i64) {
|
||||
return writeVarint64(i64ToZigzag(i64));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a double to the wire as 8 bytes.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::writeDouble(const double dub) {
|
||||
BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
|
||||
BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
|
||||
|
||||
uint64_t bits = bitwise_cast<uint64_t>(dub);
|
||||
bits = THRIFT_htolell(bits);
|
||||
trans_->write((uint8_t*)&bits, 8);
|
||||
return 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string to the wire with a varint size preceding.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::writeString(const std::string& str) {
|
||||
return writeBinary(str);
|
||||
}
|
||||
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::writeBinary(const std::string& str) {
|
||||
if(str.size() > (std::numeric_limits<uint32_t>::max)())
|
||||
throw TProtocolException(TProtocolException::SIZE_LIMIT);
|
||||
uint32_t ssize = static_cast<uint32_t>(str.size());
|
||||
uint32_t wsize = writeVarint32(ssize) ;
|
||||
// checking ssize + wsize > uint_max, but we don't want to overflow while checking for overflows.
|
||||
// transforming the check to ssize > uint_max - wsize
|
||||
if(ssize > (std::numeric_limits<uint32_t>::max)() - wsize)
|
||||
throw TProtocolException(TProtocolException::SIZE_LIMIT);
|
||||
wsize += ssize;
|
||||
trans_->write((uint8_t*)str.data(), ssize);
|
||||
return wsize;
|
||||
}
|
||||
|
||||
//
|
||||
// Internal Writing methods
|
||||
//
|
||||
|
||||
/**
|
||||
* The workhorse of writeFieldBegin. It has the option of doing a
|
||||
* 'type override' of the type header. This is used specifically in the
|
||||
* boolean field case.
|
||||
*/
|
||||
template <class Transport_>
|
||||
int32_t TCompactProtocolT<Transport_>::writeFieldBeginInternal(
|
||||
const char* name,
|
||||
const TType fieldType,
|
||||
const int16_t fieldId,
|
||||
int8_t typeOverride) {
|
||||
(void) name;
|
||||
uint32_t wsize = 0;
|
||||
|
||||
// if there's a type override, use that.
|
||||
int8_t typeToWrite = (typeOverride == -1 ? getCompactType(fieldType) : typeOverride);
|
||||
|
||||
// check if we can use delta encoding for the field id
|
||||
if (fieldId > lastFieldId_ && fieldId - lastFieldId_ <= 15) {
|
||||
// write them together
|
||||
wsize += writeByte(static_cast<int8_t>((fieldId - lastFieldId_)
|
||||
<< 4 | typeToWrite));
|
||||
} else {
|
||||
// write them separate
|
||||
wsize += writeByte(typeToWrite);
|
||||
wsize += writeI16(fieldId);
|
||||
}
|
||||
|
||||
lastFieldId_ = fieldId;
|
||||
return wsize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract method for writing the start of lists and sets. List and sets on
|
||||
* the wire differ only by the type indicator.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::writeCollectionBegin(const TType elemType,
|
||||
int32_t size) {
|
||||
uint32_t wsize = 0;
|
||||
if (size <= 14) {
|
||||
wsize += writeByte(static_cast<int8_t>(size
|
||||
<< 4 | getCompactType(elemType)));
|
||||
} else {
|
||||
wsize += writeByte(0xf0 | getCompactType(elemType));
|
||||
wsize += writeVarint32(size);
|
||||
}
|
||||
return wsize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an i32 as a varint. Results in 1-5 bytes on the wire.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::writeVarint32(uint32_t n) {
|
||||
uint8_t buf[5];
|
||||
uint32_t wsize = 0;
|
||||
|
||||
while (true) {
|
||||
if ((n & ~0x7F) == 0) {
|
||||
buf[wsize++] = (int8_t)n;
|
||||
break;
|
||||
} else {
|
||||
buf[wsize++] = (int8_t)((n & 0x7F) | 0x80);
|
||||
n >>= 7;
|
||||
}
|
||||
}
|
||||
trans_->write(buf, wsize);
|
||||
return wsize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an i64 as a varint. Results in 1-10 bytes on the wire.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::writeVarint64(uint64_t n) {
|
||||
uint8_t buf[10];
|
||||
uint32_t wsize = 0;
|
||||
|
||||
while (true) {
|
||||
if ((n & ~0x7FL) == 0) {
|
||||
buf[wsize++] = (int8_t)n;
|
||||
break;
|
||||
} else {
|
||||
buf[wsize++] = (int8_t)((n & 0x7F) | 0x80);
|
||||
n >>= 7;
|
||||
}
|
||||
}
|
||||
trans_->write(buf, wsize);
|
||||
return wsize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert l into a zigzag long. This allows negative numbers to be
|
||||
* represented compactly as a varint.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint64_t TCompactProtocolT<Transport_>::i64ToZigzag(const int64_t l) {
|
||||
return (l << 1) ^ (l >> 63);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert n into a zigzag int. This allows negative numbers to be
|
||||
* represented compactly as a varint.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::i32ToZigzag(const int32_t n) {
|
||||
return (n << 1) ^ (n >> 31);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a TType value, find the appropriate detail::compact::Types value
|
||||
*/
|
||||
template <class Transport_>
|
||||
int8_t TCompactProtocolT<Transport_>::getCompactType(const TType ttype) {
|
||||
return detail::compact::TTypeToCType[ttype];
|
||||
}
|
||||
|
||||
//
|
||||
// Reading Methods
|
||||
//
|
||||
|
||||
/**
|
||||
* Read a message header.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::readMessageBegin(
|
||||
std::string& name,
|
||||
TMessageType& messageType,
|
||||
int32_t& seqid) {
|
||||
uint32_t rsize = 0;
|
||||
int8_t protocolId;
|
||||
int8_t versionAndType;
|
||||
int8_t version;
|
||||
|
||||
rsize += readByte(protocolId);
|
||||
if (protocolId != PROTOCOL_ID) {
|
||||
throw TProtocolException(TProtocolException::BAD_VERSION, "Bad protocol identifier");
|
||||
}
|
||||
|
||||
rsize += readByte(versionAndType);
|
||||
version = (int8_t)(versionAndType & VERSION_MASK);
|
||||
if (version != VERSION_N) {
|
||||
throw TProtocolException(TProtocolException::BAD_VERSION, "Bad protocol version");
|
||||
}
|
||||
|
||||
messageType = (TMessageType)((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS);
|
||||
rsize += readVarint32(seqid);
|
||||
rsize += readString(name);
|
||||
|
||||
return rsize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a struct begin. There's nothing on the wire for this, but it is our
|
||||
* opportunity to push a new struct begin marker on the field stack.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::readStructBegin(std::string& name) {
|
||||
name = "";
|
||||
lastField_.push(lastFieldId_);
|
||||
lastFieldId_ = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Doesn't actually consume any wire data, just removes the last field for
|
||||
* this struct from the field stack.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::readStructEnd() {
|
||||
lastFieldId_ = lastField_.top();
|
||||
lastField_.pop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a field header off the wire.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::readFieldBegin(std::string& name,
|
||||
TType& fieldType,
|
||||
int16_t& fieldId) {
|
||||
(void) name;
|
||||
uint32_t rsize = 0;
|
||||
int8_t byte;
|
||||
int8_t type;
|
||||
|
||||
rsize += readByte(byte);
|
||||
type = (byte & 0x0f);
|
||||
|
||||
// if it's a stop, then we can return immediately, as the struct is over.
|
||||
if (type == T_STOP) {
|
||||
fieldType = T_STOP;
|
||||
fieldId = 0;
|
||||
return rsize;
|
||||
}
|
||||
|
||||
// mask off the 4 MSB of the type header. it could contain a field id delta.
|
||||
int16_t modifier = (int16_t)(((uint8_t)byte & 0xf0) >> 4);
|
||||
if (modifier == 0) {
|
||||
// not a delta, look ahead for the zigzag varint field id.
|
||||
rsize += readI16(fieldId);
|
||||
} else {
|
||||
fieldId = (int16_t)(lastFieldId_ + modifier);
|
||||
}
|
||||
fieldType = getTType(type);
|
||||
|
||||
// if this happens to be a boolean field, the value is encoded in the type
|
||||
if (type == detail::compact::CT_BOOLEAN_TRUE ||
|
||||
type == detail::compact::CT_BOOLEAN_FALSE) {
|
||||
// save the boolean value in a special instance variable.
|
||||
boolValue_.hasBoolValue = true;
|
||||
boolValue_.boolValue =
|
||||
(type == detail::compact::CT_BOOLEAN_TRUE ? true : false);
|
||||
}
|
||||
|
||||
// push the new field onto the field stack so we can keep the deltas going.
|
||||
lastFieldId_ = fieldId;
|
||||
return rsize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a map header off the wire. If the size is zero, skip reading the key
|
||||
* and value type. This means that 0-length maps will yield TMaps without the
|
||||
* "correct" types.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::readMapBegin(TType& keyType,
|
||||
TType& valType,
|
||||
uint32_t& size) {
|
||||
uint32_t rsize = 0;
|
||||
int8_t kvType = 0;
|
||||
int32_t msize = 0;
|
||||
|
||||
rsize += readVarint32(msize);
|
||||
if (msize != 0)
|
||||
rsize += readByte(kvType);
|
||||
|
||||
if (msize < 0) {
|
||||
throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
|
||||
} else if (container_limit_ && msize > container_limit_) {
|
||||
throw TProtocolException(TProtocolException::SIZE_LIMIT);
|
||||
}
|
||||
|
||||
keyType = getTType((int8_t)((uint8_t)kvType >> 4));
|
||||
valType = getTType((int8_t)((uint8_t)kvType & 0xf));
|
||||
size = (uint32_t)msize;
|
||||
|
||||
return rsize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a list header off the wire. If the list size is 0-14, the size will
|
||||
* be packed into the element type header. If it's a longer list, the 4 MSB
|
||||
* of the element type header will be 0xF, and a varint will follow with the
|
||||
* true size.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::readListBegin(TType& elemType,
|
||||
uint32_t& size) {
|
||||
int8_t size_and_type;
|
||||
uint32_t rsize = 0;
|
||||
int32_t lsize;
|
||||
|
||||
rsize += readByte(size_and_type);
|
||||
|
||||
lsize = ((uint8_t)size_and_type >> 4) & 0x0f;
|
||||
if (lsize == 15) {
|
||||
rsize += readVarint32(lsize);
|
||||
}
|
||||
|
||||
if (lsize < 0) {
|
||||
throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
|
||||
} else if (container_limit_ && lsize > container_limit_) {
|
||||
throw TProtocolException(TProtocolException::SIZE_LIMIT);
|
||||
}
|
||||
|
||||
elemType = getTType((int8_t)(size_and_type & 0x0f));
|
||||
size = (uint32_t)lsize;
|
||||
|
||||
return rsize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a set header off the wire. If the set size is 0-14, the size will
|
||||
* be packed into the element type header. If it's a longer set, the 4 MSB
|
||||
* of the element type header will be 0xF, and a varint will follow with the
|
||||
* true size.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::readSetBegin(TType& elemType,
|
||||
uint32_t& size) {
|
||||
return readListBegin(elemType, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a boolean off the wire. If this is a boolean field, the value should
|
||||
* already have been read during readFieldBegin, so we'll just consume the
|
||||
* pre-stored value. Otherwise, read a byte.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::readBool(bool& value) {
|
||||
if (boolValue_.hasBoolValue == true) {
|
||||
value = boolValue_.boolValue;
|
||||
boolValue_.hasBoolValue = false;
|
||||
return 0;
|
||||
} else {
|
||||
int8_t val;
|
||||
readByte(val);
|
||||
value = (val == detail::compact::CT_BOOLEAN_TRUE);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a single byte off the wire. Nothing interesting here.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::readByte(int8_t& byte) {
|
||||
uint8_t b[1];
|
||||
trans_->readAll(b, 1);
|
||||
byte = *(int8_t*)b;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an i16 from the wire as a zigzag varint.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::readI16(int16_t& i16) {
|
||||
int32_t value;
|
||||
uint32_t rsize = readVarint32(value);
|
||||
i16 = (int16_t)zigzagToI32(value);
|
||||
return rsize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an i32 from the wire as a zigzag varint.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::readI32(int32_t& i32) {
|
||||
int32_t value;
|
||||
uint32_t rsize = readVarint32(value);
|
||||
i32 = zigzagToI32(value);
|
||||
return rsize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an i64 from the wire as a zigzag varint.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::readI64(int64_t& i64) {
|
||||
int64_t value;
|
||||
uint32_t rsize = readVarint64(value);
|
||||
i64 = zigzagToI64(value);
|
||||
return rsize;
|
||||
}
|
||||
|
||||
/**
|
||||
* No magic here - just read a double off the wire.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::readDouble(double& dub) {
|
||||
BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
|
||||
BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
|
||||
|
||||
union {
|
||||
uint64_t bits;
|
||||
uint8_t b[8];
|
||||
} u;
|
||||
trans_->readAll(u.b, 8);
|
||||
u.bits = THRIFT_letohll(u.bits);
|
||||
dub = bitwise_cast<double>(u.bits);
|
||||
return 8;
|
||||
}
|
||||
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::readString(std::string& str) {
|
||||
return readBinary(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a byte[] from the wire.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::readBinary(std::string& str) {
|
||||
int32_t rsize = 0;
|
||||
int32_t size;
|
||||
|
||||
rsize += readVarint32(size);
|
||||
// Catch empty string case
|
||||
if (size == 0) {
|
||||
str = "";
|
||||
return rsize;
|
||||
}
|
||||
|
||||
// Catch error cases
|
||||
if (size < 0) {
|
||||
throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
|
||||
}
|
||||
if (string_limit_ > 0 && size > string_limit_) {
|
||||
throw TProtocolException(TProtocolException::SIZE_LIMIT);
|
||||
}
|
||||
|
||||
// Use the heap here to prevent stack overflow for v. large strings
|
||||
if (size > string_buf_size_ || string_buf_ == NULL) {
|
||||
void* new_string_buf = std::realloc(string_buf_, (uint32_t)size);
|
||||
if (new_string_buf == NULL) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
string_buf_ = (uint8_t*)new_string_buf;
|
||||
string_buf_size_ = size;
|
||||
}
|
||||
trans_->readAll(string_buf_, size);
|
||||
str.assign((char*)string_buf_, size);
|
||||
|
||||
return rsize + (uint32_t)size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an i32 from the wire as a varint. The MSB of each byte is set
|
||||
* if there is another byte to follow. This can read up to 5 bytes.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::readVarint32(int32_t& i32) {
|
||||
int64_t val;
|
||||
uint32_t rsize = readVarint64(val);
|
||||
i32 = (int32_t)val;
|
||||
return rsize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an i64 from the wire as a proper varint. The MSB of each byte is set
|
||||
* if there is another byte to follow. This can read up to 10 bytes.
|
||||
*/
|
||||
template <class Transport_>
|
||||
uint32_t TCompactProtocolT<Transport_>::readVarint64(int64_t& i64) {
|
||||
uint32_t rsize = 0;
|
||||
uint64_t val = 0;
|
||||
int shift = 0;
|
||||
uint8_t buf[10]; // 64 bits / (7 bits/byte) = 10 bytes.
|
||||
uint32_t buf_size = sizeof(buf);
|
||||
const uint8_t* borrowed = trans_->borrow(buf, &buf_size);
|
||||
|
||||
// Fast path.
|
||||
if (borrowed != NULL) {
|
||||
while (true) {
|
||||
uint8_t byte = borrowed[rsize];
|
||||
rsize++;
|
||||
val |= (uint64_t)(byte & 0x7f) << shift;
|
||||
shift += 7;
|
||||
if (!(byte & 0x80)) {
|
||||
i64 = val;
|
||||
trans_->consume(rsize);
|
||||
return rsize;
|
||||
}
|
||||
// Have to check for invalid data so we don't crash.
|
||||
if (UNLIKELY(rsize == sizeof(buf))) {
|
||||
throw TProtocolException(TProtocolException::INVALID_DATA, "Variable-length int over 10 bytes.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Slow path.
|
||||
else {
|
||||
while (true) {
|
||||
uint8_t byte;
|
||||
rsize += trans_->readAll(&byte, 1);
|
||||
val |= (uint64_t)(byte & 0x7f) << shift;
|
||||
shift += 7;
|
||||
if (!(byte & 0x80)) {
|
||||
i64 = val;
|
||||
return rsize;
|
||||
}
|
||||
// Might as well check for invalid data on the slow path too.
|
||||
if (UNLIKELY(rsize >= sizeof(buf))) {
|
||||
throw TProtocolException(TProtocolException::INVALID_DATA, "Variable-length int over 10 bytes.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from zigzag int to int.
|
||||
*/
|
||||
template <class Transport_>
|
||||
int32_t TCompactProtocolT<Transport_>::zigzagToI32(uint32_t n) {
|
||||
return (n >> 1) ^ static_cast<uint32_t>(-static_cast<int32_t>(n & 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from zigzag long to long.
|
||||
*/
|
||||
template <class Transport_>
|
||||
int64_t TCompactProtocolT<Transport_>::zigzagToI64(uint64_t n) {
|
||||
return (n >> 1) ^ static_cast<uint64_t>(-static_cast<int64_t>(n & 1));
|
||||
}
|
||||
|
||||
template <class Transport_>
|
||||
TType TCompactProtocolT<Transport_>::getTType(int8_t type) {
|
||||
switch (type) {
|
||||
case T_STOP:
|
||||
return T_STOP;
|
||||
case detail::compact::CT_BOOLEAN_FALSE:
|
||||
case detail::compact::CT_BOOLEAN_TRUE:
|
||||
return T_BOOL;
|
||||
case detail::compact::CT_BYTE:
|
||||
return T_BYTE;
|
||||
case detail::compact::CT_I16:
|
||||
return T_I16;
|
||||
case detail::compact::CT_I32:
|
||||
return T_I32;
|
||||
case detail::compact::CT_I64:
|
||||
return T_I64;
|
||||
case detail::compact::CT_DOUBLE:
|
||||
return T_DOUBLE;
|
||||
case detail::compact::CT_BINARY:
|
||||
return T_STRING;
|
||||
case detail::compact::CT_LIST:
|
||||
return T_LIST;
|
||||
case detail::compact::CT_SET:
|
||||
return T_SET;
|
||||
case detail::compact::CT_MAP:
|
||||
return T_MAP;
|
||||
case detail::compact::CT_STRUCT:
|
||||
return T_STRUCT;
|
||||
default:
|
||||
throw TException(std::string("don't know what type: ") + (char)type);
|
||||
}
|
||||
}
|
||||
|
||||
}}} // apache::thrift::protocol
|
||||
|
||||
#endif // _THRIFT_PROTOCOL_TCOMPACTPROTOCOL_TCC_
|
394
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TDebugProtocol.cpp
generated
vendored
Normal file
394
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TDebugProtocol.cpp
generated
vendored
Normal file
|
@ -0,0 +1,394 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/protocol/TDebugProtocol.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <stdexcept>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
using std::string;
|
||||
|
||||
static string byte_to_hex(const uint8_t byte) {
|
||||
char buf[3];
|
||||
int ret = std::sprintf(buf, "%02x", (int)byte);
|
||||
THRIFT_UNUSED_VARIABLE(ret);
|
||||
assert(ret == 2);
|
||||
assert(buf[2] == '\0');
|
||||
return buf;
|
||||
}
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace protocol {
|
||||
|
||||
string TDebugProtocol::fieldTypeName(TType type) {
|
||||
switch (type) {
|
||||
case T_STOP:
|
||||
return "stop";
|
||||
case T_VOID:
|
||||
return "void";
|
||||
case T_BOOL:
|
||||
return "bool";
|
||||
case T_BYTE:
|
||||
return "byte";
|
||||
case T_I16:
|
||||
return "i16";
|
||||
case T_I32:
|
||||
return "i32";
|
||||
case T_U64:
|
||||
return "u64";
|
||||
case T_I64:
|
||||
return "i64";
|
||||
case T_DOUBLE:
|
||||
return "double";
|
||||
case T_STRING:
|
||||
return "string";
|
||||
case T_STRUCT:
|
||||
return "struct";
|
||||
case T_MAP:
|
||||
return "map";
|
||||
case T_SET:
|
||||
return "set";
|
||||
case T_LIST:
|
||||
return "list";
|
||||
case T_UTF8:
|
||||
return "utf8";
|
||||
case T_UTF16:
|
||||
return "utf16";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void TDebugProtocol::indentUp() {
|
||||
indent_str_ += string(indent_inc, ' ');
|
||||
}
|
||||
|
||||
void TDebugProtocol::indentDown() {
|
||||
if (indent_str_.length() < (string::size_type)indent_inc) {
|
||||
throw TProtocolException(TProtocolException::INVALID_DATA);
|
||||
}
|
||||
indent_str_.erase(indent_str_.length() - indent_inc);
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writePlain(const string& str) {
|
||||
if (str.length() > (std::numeric_limits<uint32_t>::max)())
|
||||
throw TProtocolException(TProtocolException::SIZE_LIMIT);
|
||||
trans_->write((uint8_t*)str.data(), static_cast<uint32_t>(str.length()));
|
||||
return static_cast<uint32_t>(str.length());
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeIndented(const string& str) {
|
||||
if (str.length() > (std::numeric_limits<uint32_t>::max)())
|
||||
throw TProtocolException(TProtocolException::SIZE_LIMIT);
|
||||
if (indent_str_.length() > (std::numeric_limits<uint32_t>::max)())
|
||||
throw TProtocolException(TProtocolException::SIZE_LIMIT);
|
||||
uint64_t total_len = indent_str_.length() + str.length();
|
||||
if (total_len > (std::numeric_limits<uint32_t>::max)())
|
||||
throw TProtocolException(TProtocolException::SIZE_LIMIT);
|
||||
trans_->write((uint8_t*)indent_str_.data(), static_cast<uint32_t>(indent_str_.length()));
|
||||
trans_->write((uint8_t*)str.data(), static_cast<uint32_t>(str.length()));
|
||||
return static_cast<uint32_t>(indent_str_.length() + str.length());
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::startItem() {
|
||||
uint32_t size;
|
||||
|
||||
switch (write_state_.back()) {
|
||||
case UNINIT:
|
||||
// XXX figure out what to do here.
|
||||
// throw TProtocolException(TProtocolException::INVALID_DATA);
|
||||
// return writeIndented(str);
|
||||
return 0;
|
||||
case STRUCT:
|
||||
return 0;
|
||||
case SET:
|
||||
return writeIndented("");
|
||||
case MAP_KEY:
|
||||
return writeIndented("");
|
||||
case MAP_VALUE:
|
||||
return writePlain(" -> ");
|
||||
case LIST:
|
||||
size = writeIndented("[" + boost::lexical_cast<string>(list_idx_.back()) + "] = ");
|
||||
list_idx_.back()++;
|
||||
return size;
|
||||
default:
|
||||
throw std::logic_error("Invalid enum value.");
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::endItem() {
|
||||
// uint32_t size;
|
||||
|
||||
switch (write_state_.back()) {
|
||||
case UNINIT:
|
||||
// XXX figure out what to do here.
|
||||
// throw TProtocolException(TProtocolException::INVALID_DATA);
|
||||
// return writeIndented(str);
|
||||
return 0;
|
||||
case STRUCT:
|
||||
return writePlain(",\n");
|
||||
case SET:
|
||||
return writePlain(",\n");
|
||||
case MAP_KEY:
|
||||
write_state_.back() = MAP_VALUE;
|
||||
return 0;
|
||||
case MAP_VALUE:
|
||||
write_state_.back() = MAP_KEY;
|
||||
return writePlain(",\n");
|
||||
case LIST:
|
||||
return writePlain(",\n");
|
||||
default:
|
||||
throw std::logic_error("Invalid enum value.");
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeItem(const std::string& str) {
|
||||
uint32_t size = 0;
|
||||
size += startItem();
|
||||
size += writePlain(str);
|
||||
size += endItem();
|
||||
return size;
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeMessageBegin(const std::string& name,
|
||||
const TMessageType messageType,
|
||||
const int32_t seqid) {
|
||||
(void)seqid;
|
||||
string mtype;
|
||||
switch (messageType) {
|
||||
case T_CALL:
|
||||
mtype = "call";
|
||||
break;
|
||||
case T_REPLY:
|
||||
mtype = "reply";
|
||||
break;
|
||||
case T_EXCEPTION:
|
||||
mtype = "exn";
|
||||
break;
|
||||
case T_ONEWAY:
|
||||
mtype = "oneway";
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t size = writeIndented("(" + mtype + ") " + name + "(");
|
||||
indentUp();
|
||||
return size;
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeMessageEnd() {
|
||||
indentDown();
|
||||
return writeIndented(")\n");
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeStructBegin(const char* name) {
|
||||
uint32_t size = 0;
|
||||
size += startItem();
|
||||
size += writePlain(string(name) + " {\n");
|
||||
indentUp();
|
||||
write_state_.push_back(STRUCT);
|
||||
return size;
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeStructEnd() {
|
||||
indentDown();
|
||||
write_state_.pop_back();
|
||||
uint32_t size = 0;
|
||||
size += writeIndented("}");
|
||||
size += endItem();
|
||||
return size;
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeFieldBegin(const char* name,
|
||||
const TType fieldType,
|
||||
const int16_t fieldId) {
|
||||
// sprintf(id_str, "%02d", fieldId);
|
||||
string id_str = boost::lexical_cast<string>(fieldId);
|
||||
if (id_str.length() == 1)
|
||||
id_str = '0' + id_str;
|
||||
|
||||
return writeIndented(id_str + ": " + name + " (" + fieldTypeName(fieldType) + ") = ");
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeFieldEnd() {
|
||||
assert(write_state_.back() == STRUCT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeFieldStop() {
|
||||
return 0;
|
||||
// writeIndented("***STOP***\n");
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeMapBegin(const TType keyType,
|
||||
const TType valType,
|
||||
const uint32_t size) {
|
||||
// TODO(dreiss): Optimize short maps?
|
||||
uint32_t bsize = 0;
|
||||
bsize += startItem();
|
||||
bsize += writePlain(
|
||||
"map<" + fieldTypeName(keyType) + "," + fieldTypeName(valType) + ">"
|
||||
"[" + boost::lexical_cast<string>(size) + "] {\n");
|
||||
indentUp();
|
||||
write_state_.push_back(MAP_KEY);
|
||||
return bsize;
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeMapEnd() {
|
||||
indentDown();
|
||||
write_state_.pop_back();
|
||||
uint32_t size = 0;
|
||||
size += writeIndented("}");
|
||||
size += endItem();
|
||||
return size;
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeListBegin(const TType elemType, const uint32_t size) {
|
||||
// TODO(dreiss): Optimize short arrays.
|
||||
uint32_t bsize = 0;
|
||||
bsize += startItem();
|
||||
bsize += writePlain(
|
||||
"list<" + fieldTypeName(elemType) + ">"
|
||||
"[" + boost::lexical_cast<string>(size) + "] {\n");
|
||||
indentUp();
|
||||
write_state_.push_back(LIST);
|
||||
list_idx_.push_back(0);
|
||||
return bsize;
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeListEnd() {
|
||||
indentDown();
|
||||
write_state_.pop_back();
|
||||
list_idx_.pop_back();
|
||||
uint32_t size = 0;
|
||||
size += writeIndented("}");
|
||||
size += endItem();
|
||||
return size;
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeSetBegin(const TType elemType, const uint32_t size) {
|
||||
// TODO(dreiss): Optimize short sets.
|
||||
uint32_t bsize = 0;
|
||||
bsize += startItem();
|
||||
bsize += writePlain(
|
||||
"set<" + fieldTypeName(elemType) + ">"
|
||||
"[" + boost::lexical_cast<string>(size) + "] {\n");
|
||||
indentUp();
|
||||
write_state_.push_back(SET);
|
||||
return bsize;
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeSetEnd() {
|
||||
indentDown();
|
||||
write_state_.pop_back();
|
||||
uint32_t size = 0;
|
||||
size += writeIndented("}");
|
||||
size += endItem();
|
||||
return size;
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeBool(const bool value) {
|
||||
return writeItem(value ? "true" : "false");
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeByte(const int8_t byte) {
|
||||
return writeItem("0x" + byte_to_hex(byte));
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeI16(const int16_t i16) {
|
||||
return writeItem(boost::lexical_cast<string>(i16));
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeI32(const int32_t i32) {
|
||||
return writeItem(boost::lexical_cast<string>(i32));
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeI64(const int64_t i64) {
|
||||
return writeItem(boost::lexical_cast<string>(i64));
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeDouble(const double dub) {
|
||||
return writeItem(boost::lexical_cast<string>(dub));
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeString(const string& str) {
|
||||
// XXX Raw/UTF-8?
|
||||
|
||||
string to_show = str;
|
||||
if (to_show.length() > (string::size_type)string_limit_) {
|
||||
to_show = str.substr(0, string_prefix_size_);
|
||||
to_show += "[...](" + boost::lexical_cast<string>(str.length()) + ")";
|
||||
}
|
||||
|
||||
string output = "\"";
|
||||
|
||||
for (string::const_iterator it = to_show.begin(); it != to_show.end(); ++it) {
|
||||
if (*it == '\\') {
|
||||
output += "\\\\";
|
||||
} else if (*it == '"') {
|
||||
output += "\\\"";
|
||||
// passing characters <0 to std::isprint causes asserts. isprint takes an
|
||||
// int, so we need to be careful of sign extension
|
||||
} else if (std::isprint((unsigned char)*it)) {
|
||||
output += *it;
|
||||
} else {
|
||||
switch (*it) {
|
||||
case '\a':
|
||||
output += "\\a";
|
||||
break;
|
||||
case '\b':
|
||||
output += "\\b";
|
||||
break;
|
||||
case '\f':
|
||||
output += "\\f";
|
||||
break;
|
||||
case '\n':
|
||||
output += "\\n";
|
||||
break;
|
||||
case '\r':
|
||||
output += "\\r";
|
||||
break;
|
||||
case '\t':
|
||||
output += "\\t";
|
||||
break;
|
||||
case '\v':
|
||||
output += "\\v";
|
||||
break;
|
||||
default:
|
||||
output += "\\x";
|
||||
output += byte_to_hex(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output += '\"';
|
||||
return writeItem(output);
|
||||
}
|
||||
|
||||
uint32_t TDebugProtocol::writeBinary(const string& str) {
|
||||
// XXX Hex?
|
||||
return TDebugProtocol::writeString(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::protocol
|
204
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TDebugProtocol.h
generated
vendored
Normal file
204
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TDebugProtocol.h
generated
vendored
Normal file
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_PROTOCOL_TDEBUGPROTOCOL_H_
|
||||
#define _THRIFT_PROTOCOL_TDEBUGPROTOCOL_H_ 1
|
||||
|
||||
#include <thrift/protocol/TVirtualProtocol.h>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace protocol {
|
||||
|
||||
/*
|
||||
|
||||
!!! EXPERIMENTAL CODE !!!
|
||||
|
||||
This protocol is very much a work in progress.
|
||||
It doesn't handle many cases properly.
|
||||
It throws exceptions in many cases.
|
||||
It probably segfaults in many cases.
|
||||
Bug reports and feature requests are welcome.
|
||||
Complaints are not. :R
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* Protocol that prints the payload in a nice human-readable format.
|
||||
* Reading from this protocol is not supported.
|
||||
*
|
||||
*/
|
||||
class TDebugProtocol : public TVirtualProtocol<TDebugProtocol> {
|
||||
private:
|
||||
enum write_state_t { UNINIT, STRUCT, LIST, SET, MAP_KEY, MAP_VALUE };
|
||||
|
||||
public:
|
||||
TDebugProtocol(boost::shared_ptr<TTransport> trans)
|
||||
: TVirtualProtocol<TDebugProtocol>(trans),
|
||||
trans_(trans.get()),
|
||||
string_limit_(DEFAULT_STRING_LIMIT),
|
||||
string_prefix_size_(DEFAULT_STRING_PREFIX_SIZE) {
|
||||
write_state_.push_back(UNINIT);
|
||||
}
|
||||
|
||||
static const int32_t DEFAULT_STRING_LIMIT = 256;
|
||||
static const int32_t DEFAULT_STRING_PREFIX_SIZE = 16;
|
||||
|
||||
void setStringSizeLimit(int32_t string_limit) { string_limit_ = string_limit; }
|
||||
|
||||
void setStringPrefixSize(int32_t string_prefix_size) { string_prefix_size_ = string_prefix_size; }
|
||||
|
||||
uint32_t writeMessageBegin(const std::string& name,
|
||||
const TMessageType messageType,
|
||||
const int32_t seqid);
|
||||
|
||||
uint32_t writeMessageEnd();
|
||||
|
||||
uint32_t writeStructBegin(const char* name);
|
||||
|
||||
uint32_t writeStructEnd();
|
||||
|
||||
uint32_t writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId);
|
||||
|
||||
uint32_t writeFieldEnd();
|
||||
|
||||
uint32_t writeFieldStop();
|
||||
|
||||
uint32_t writeMapBegin(const TType keyType, const TType valType, const uint32_t size);
|
||||
|
||||
uint32_t writeMapEnd();
|
||||
|
||||
uint32_t writeListBegin(const TType elemType, const uint32_t size);
|
||||
|
||||
uint32_t writeListEnd();
|
||||
|
||||
uint32_t writeSetBegin(const TType elemType, const uint32_t size);
|
||||
|
||||
uint32_t writeSetEnd();
|
||||
|
||||
uint32_t writeBool(const bool value);
|
||||
|
||||
uint32_t writeByte(const int8_t byte);
|
||||
|
||||
uint32_t writeI16(const int16_t i16);
|
||||
|
||||
uint32_t writeI32(const int32_t i32);
|
||||
|
||||
uint32_t writeI64(const int64_t i64);
|
||||
|
||||
uint32_t writeDouble(const double dub);
|
||||
|
||||
uint32_t writeString(const std::string& str);
|
||||
|
||||
uint32_t writeBinary(const std::string& str);
|
||||
|
||||
private:
|
||||
void indentUp();
|
||||
void indentDown();
|
||||
uint32_t writePlain(const std::string& str);
|
||||
uint32_t writeIndented(const std::string& str);
|
||||
uint32_t startItem();
|
||||
uint32_t endItem();
|
||||
uint32_t writeItem(const std::string& str);
|
||||
|
||||
static std::string fieldTypeName(TType type);
|
||||
|
||||
TTransport* trans_;
|
||||
|
||||
int32_t string_limit_;
|
||||
int32_t string_prefix_size_;
|
||||
|
||||
std::string indent_str_;
|
||||
static const int indent_inc = 2;
|
||||
|
||||
std::vector<write_state_t> write_state_;
|
||||
std::vector<int> list_idx_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs debug protocol handlers
|
||||
*/
|
||||
class TDebugProtocolFactory : public TProtocolFactory {
|
||||
public:
|
||||
TDebugProtocolFactory() {}
|
||||
virtual ~TDebugProtocolFactory() {}
|
||||
|
||||
boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) {
|
||||
return boost::shared_ptr<TProtocol>(new TDebugProtocol(trans));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::protocol
|
||||
|
||||
// TODO(dreiss): Move (part of) ThriftDebugString into a .cpp file and remove this.
|
||||
#include <thrift/transport/TBufferTransports.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
|
||||
template <typename ThriftStruct>
|
||||
std::string ThriftDebugString(const ThriftStruct& ts) {
|
||||
using namespace apache::thrift::transport;
|
||||
using namespace apache::thrift::protocol;
|
||||
TMemoryBuffer* buffer = new TMemoryBuffer;
|
||||
boost::shared_ptr<TTransport> trans(buffer);
|
||||
TDebugProtocol protocol(trans);
|
||||
|
||||
ts.write(&protocol);
|
||||
|
||||
uint8_t* buf;
|
||||
uint32_t size;
|
||||
buffer->getBuffer(&buf, &size);
|
||||
return std::string((char*)buf, (unsigned int)size);
|
||||
}
|
||||
|
||||
// TODO(dreiss): This is badly broken. Don't use it unless you are me.
|
||||
#if 0
|
||||
template<typename Object>
|
||||
std::string DebugString(const std::vector<Object>& vec) {
|
||||
using namespace apache::thrift::transport;
|
||||
using namespace apache::thrift::protocol;
|
||||
TMemoryBuffer* buffer = new TMemoryBuffer;
|
||||
boost::shared_ptr<TTransport> trans(buffer);
|
||||
TDebugProtocol protocol(trans);
|
||||
|
||||
// I am gross!
|
||||
protocol.writeStructBegin("SomeRandomVector");
|
||||
|
||||
// TODO: Fix this with a trait.
|
||||
protocol.writeListBegin((TType)99, vec.size());
|
||||
typename std::vector<Object>::const_iterator it;
|
||||
for (it = vec.begin(); it != vec.end(); ++it) {
|
||||
it->write(&protocol);
|
||||
}
|
||||
protocol.writeListEnd();
|
||||
|
||||
uint8_t* buf;
|
||||
uint32_t size;
|
||||
buffer->getBuffer(&buf, &size);
|
||||
return std::string((char*)buf, (unsigned int)size);
|
||||
}
|
||||
#endif // 0
|
||||
}
|
||||
} // apache::thrift
|
||||
|
||||
#endif // #ifndef _THRIFT_PROTOCOL_TDEBUGPROTOCOL_H_
|
254
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/THeaderProtocol.cpp
generated
vendored
Normal file
254
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/THeaderProtocol.cpp
generated
vendored
Normal file
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
#ifndef THRIFT_PROTOCOL_THEADERPROTOCOL_CPP_
|
||||
#define THRIFT_PROTOCOL_THEADERPROTOCOL_CPP_ 1
|
||||
|
||||
#include <thrift/protocol/THeaderProtocol.h>
|
||||
#include <thrift/protocol/TCompactProtocol.h>
|
||||
#include <thrift/protocol/TBinaryProtocol.h>
|
||||
#include <thrift/TApplicationException.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace protocol {
|
||||
|
||||
void THeaderProtocol::resetProtocol() {
|
||||
if (proto_ && protoId_ == trans_->getProtocolId()) {
|
||||
return;
|
||||
}
|
||||
|
||||
protoId_ = trans_->getProtocolId();
|
||||
|
||||
switch (protoId_) {
|
||||
case T_BINARY_PROTOCOL:
|
||||
proto_ = boost::make_shared<TBinaryProtocolT<THeaderTransport> >(trans_);
|
||||
break;
|
||||
|
||||
case T_COMPACT_PROTOCOL:
|
||||
proto_ = boost::make_shared<TCompactProtocolT<THeaderTransport> >(trans_);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw TApplicationException(TApplicationException::INVALID_PROTOCOL,
|
||||
"Unknown protocol requested");
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::writeMessageBegin(const std::string& name,
|
||||
const TMessageType messageType,
|
||||
const int32_t seqId) {
|
||||
resetProtocol(); // Reset in case we changed protocols
|
||||
trans_->setSequenceNumber(seqId);
|
||||
return proto_->writeMessageBegin(name, messageType, seqId);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::writeMessageEnd() {
|
||||
return proto_->writeMessageEnd();
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::writeStructBegin(const char* name) {
|
||||
return proto_->writeStructBegin(name);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::writeStructEnd() {
|
||||
return proto_->writeStructEnd();
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::writeFieldBegin(const char* name,
|
||||
const TType fieldType,
|
||||
const int16_t fieldId) {
|
||||
return proto_->writeFieldBegin(name, fieldType, fieldId);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::writeFieldEnd() {
|
||||
return proto_->writeFieldEnd();
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::writeFieldStop() {
|
||||
return proto_->writeFieldStop();
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::writeMapBegin(const TType keyType,
|
||||
const TType valType,
|
||||
const uint32_t size) {
|
||||
return proto_->writeMapBegin(keyType, valType, size);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::writeMapEnd() {
|
||||
return proto_->writeMapEnd();
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::writeListBegin(const TType elemType, const uint32_t size) {
|
||||
return proto_->writeListBegin(elemType, size);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::writeListEnd() {
|
||||
return proto_->writeListEnd();
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::writeSetBegin(const TType elemType, const uint32_t size) {
|
||||
return proto_->writeSetBegin(elemType, size);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::writeSetEnd() {
|
||||
return proto_->writeSetEnd();
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::writeBool(const bool value) {
|
||||
return proto_->writeBool(value);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::writeByte(const int8_t byte) {
|
||||
return proto_->writeByte(byte);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::writeI16(const int16_t i16) {
|
||||
return proto_->writeI16(i16);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::writeI32(const int32_t i32) {
|
||||
return proto_->writeI32(i32);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::writeI64(const int64_t i64) {
|
||||
return proto_->writeI64(i64);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::writeDouble(const double dub) {
|
||||
return proto_->writeDouble(dub);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::writeString(const std::string& str) {
|
||||
return proto_->writeString(str);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::writeBinary(const std::string& str) {
|
||||
return proto_->writeBinary(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reading functions
|
||||
*/
|
||||
|
||||
uint32_t THeaderProtocol::readMessageBegin(std::string& name,
|
||||
TMessageType& messageType,
|
||||
int32_t& seqId) {
|
||||
// Read the next frame, and change protocols if needed
|
||||
try {
|
||||
trans_->resetProtocol();
|
||||
resetProtocol();
|
||||
} catch (const TApplicationException& ex) {
|
||||
writeMessageBegin("", T_EXCEPTION, 0);
|
||||
ex.write((TProtocol*)this);
|
||||
writeMessageEnd();
|
||||
trans_->flush();
|
||||
|
||||
// The framing is still good, but we don't know about this protocol.
|
||||
// In the future, this could be made a client-side only error if
|
||||
// connection pooling is used.
|
||||
throw ex;
|
||||
}
|
||||
return proto_->readMessageBegin(name, messageType, seqId);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::readMessageEnd() {
|
||||
return proto_->readMessageEnd();
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::readStructBegin(std::string& name) {
|
||||
return proto_->readStructBegin(name);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::readStructEnd() {
|
||||
return proto_->readStructEnd();
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId) {
|
||||
return proto_->readFieldBegin(name, fieldType, fieldId);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::readFieldEnd() {
|
||||
return proto_->readFieldEnd();
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::readMapBegin(TType& keyType, TType& valType, uint32_t& size) {
|
||||
return proto_->readMapBegin(keyType, valType, size);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::readMapEnd() {
|
||||
return proto_->readMapEnd();
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::readListBegin(TType& elemType, uint32_t& size) {
|
||||
return proto_->readListBegin(elemType, size);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::readListEnd() {
|
||||
return proto_->readListEnd();
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::readSetBegin(TType& elemType, uint32_t& size) {
|
||||
return proto_->readSetBegin(elemType, size);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::readSetEnd() {
|
||||
return proto_->readSetEnd();
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::readBool(bool& value) {
|
||||
return proto_->readBool(value);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::readByte(int8_t& byte) {
|
||||
return proto_->readByte(byte);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::readI16(int16_t& i16) {
|
||||
return proto_->readI16(i16);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::readI32(int32_t& i32) {
|
||||
return proto_->readI32(i32);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::readI64(int64_t& i64) {
|
||||
return proto_->readI64(i64);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::readDouble(double& dub) {
|
||||
return proto_->readDouble(dub);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::readString(std::string& str) {
|
||||
return proto_->readString(str);
|
||||
}
|
||||
|
||||
uint32_t THeaderProtocol::readBinary(std::string& binary) {
|
||||
return proto_->readBinary(binary);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::protocol
|
||||
|
||||
#endif // #ifndef THRIFT_PROTOCOL_THEADERPROTOCOL_CPP_
|
210
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/THeaderProtocol.h
generated
vendored
Normal file
210
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/THeaderProtocol.h
generated
vendored
Normal file
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef THRIFT_PROTOCOL_THEADERPROTOCOL_H_
|
||||
#define THRIFT_PROTOCOL_THEADERPROTOCOL_H_ 1
|
||||
|
||||
#include <thrift/protocol/TProtocol.h>
|
||||
#include <thrift/protocol/TProtocolTypes.h>
|
||||
#include <thrift/protocol/TVirtualProtocol.h>
|
||||
#include <thrift/transport/THeaderTransport.h>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
using apache::thrift::transport::THeaderTransport;
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace protocol {
|
||||
|
||||
/**
|
||||
* The header protocol for thrift. Reads unframed, framed, header format,
|
||||
* and http
|
||||
*
|
||||
*/
|
||||
class THeaderProtocol : public TVirtualProtocol<THeaderProtocol> {
|
||||
protected:
|
||||
public:
|
||||
void resetProtocol();
|
||||
|
||||
explicit THeaderProtocol(const boost::shared_ptr<TTransport>& trans,
|
||||
uint16_t protoId = T_COMPACT_PROTOCOL)
|
||||
: TVirtualProtocol<THeaderProtocol>(boost::shared_ptr<TTransport>(new THeaderTransport(trans))),
|
||||
trans_(boost::dynamic_pointer_cast<THeaderTransport>(this->getTransport())),
|
||||
protoId_(protoId) {
|
||||
trans_->setProtocolId(protoId);
|
||||
resetProtocol();
|
||||
}
|
||||
|
||||
THeaderProtocol(const boost::shared_ptr<TTransport>& inTrans,
|
||||
const boost::shared_ptr<TTransport>& outTrans,
|
||||
uint16_t protoId = T_COMPACT_PROTOCOL)
|
||||
: TVirtualProtocol<THeaderProtocol>(
|
||||
boost::shared_ptr<TTransport>(new THeaderTransport(inTrans, outTrans))),
|
||||
trans_(boost::dynamic_pointer_cast<THeaderTransport>(this->getTransport())),
|
||||
protoId_(protoId) {
|
||||
trans_->setProtocolId(protoId);
|
||||
resetProtocol();
|
||||
}
|
||||
|
||||
~THeaderProtocol() {}
|
||||
|
||||
/**
|
||||
* Functions to work with headers by calling into THeaderTransport
|
||||
*/
|
||||
void setProtocolId(uint16_t protoId) {
|
||||
trans_->setProtocolId(protoId);
|
||||
resetProtocol();
|
||||
}
|
||||
|
||||
typedef THeaderTransport::StringToStringMap StringToStringMap;
|
||||
|
||||
// these work with write headers
|
||||
void setHeader(const std::string& key, const std::string& value) {
|
||||
trans_->setHeader(key, value);
|
||||
}
|
||||
|
||||
void clearHeaders() { trans_->clearHeaders(); }
|
||||
|
||||
StringToStringMap& getWriteHeaders() { return trans_->getWriteHeaders(); }
|
||||
|
||||
// these work with read headers
|
||||
const StringToStringMap& getHeaders() const { return trans_->getHeaders(); }
|
||||
|
||||
/**
|
||||
* Writing functions.
|
||||
*/
|
||||
|
||||
/*ol*/ uint32_t writeMessageBegin(const std::string& name,
|
||||
const TMessageType messageType,
|
||||
const int32_t seqId);
|
||||
|
||||
/*ol*/ uint32_t writeMessageEnd();
|
||||
|
||||
uint32_t writeStructBegin(const char* name);
|
||||
|
||||
uint32_t writeStructEnd();
|
||||
|
||||
uint32_t writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId);
|
||||
|
||||
uint32_t writeFieldEnd();
|
||||
|
||||
uint32_t writeFieldStop();
|
||||
|
||||
uint32_t writeMapBegin(const TType keyType, const TType valType, const uint32_t size);
|
||||
|
||||
uint32_t writeMapEnd();
|
||||
|
||||
uint32_t writeListBegin(const TType elemType, const uint32_t size);
|
||||
|
||||
uint32_t writeListEnd();
|
||||
|
||||
uint32_t writeSetBegin(const TType elemType, const uint32_t size);
|
||||
|
||||
uint32_t writeSetEnd();
|
||||
|
||||
uint32_t writeBool(const bool value);
|
||||
|
||||
uint32_t writeByte(const int8_t byte);
|
||||
|
||||
uint32_t writeI16(const int16_t i16);
|
||||
|
||||
uint32_t writeI32(const int32_t i32);
|
||||
|
||||
uint32_t writeI64(const int64_t i64);
|
||||
|
||||
uint32_t writeDouble(const double dub);
|
||||
|
||||
uint32_t writeString(const std::string& str);
|
||||
|
||||
uint32_t writeBinary(const std::string& str);
|
||||
|
||||
/**
|
||||
* Reading functions
|
||||
*/
|
||||
|
||||
/*ol*/ uint32_t readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqId);
|
||||
|
||||
/*ol*/ uint32_t readMessageEnd();
|
||||
|
||||
uint32_t readStructBegin(std::string& name);
|
||||
|
||||
uint32_t readStructEnd();
|
||||
|
||||
uint32_t readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId);
|
||||
|
||||
uint32_t readFieldEnd();
|
||||
|
||||
uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size);
|
||||
|
||||
uint32_t readMapEnd();
|
||||
|
||||
uint32_t readListBegin(TType& elemType, uint32_t& size);
|
||||
|
||||
uint32_t readListEnd();
|
||||
|
||||
uint32_t readSetBegin(TType& elemType, uint32_t& size);
|
||||
|
||||
uint32_t readSetEnd();
|
||||
|
||||
uint32_t readBool(bool& value);
|
||||
// Provide the default readBool() implementation for std::vector<bool>
|
||||
using TVirtualProtocol<THeaderProtocol>::readBool;
|
||||
|
||||
uint32_t readByte(int8_t& byte);
|
||||
|
||||
uint32_t readI16(int16_t& i16);
|
||||
|
||||
uint32_t readI32(int32_t& i32);
|
||||
|
||||
uint32_t readI64(int64_t& i64);
|
||||
|
||||
uint32_t readDouble(double& dub);
|
||||
|
||||
uint32_t readString(std::string& str);
|
||||
|
||||
uint32_t readBinary(std::string& binary);
|
||||
|
||||
protected:
|
||||
boost::shared_ptr<THeaderTransport> trans_;
|
||||
|
||||
boost::shared_ptr<TProtocol> proto_;
|
||||
uint32_t protoId_;
|
||||
};
|
||||
|
||||
class THeaderProtocolFactory : public TProtocolFactory {
|
||||
public:
|
||||
virtual boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<transport::TTransport> trans) {
|
||||
THeaderProtocol* headerProtocol
|
||||
= new THeaderProtocol(trans, boost::shared_ptr<transport::TTransport>(), T_BINARY_PROTOCOL);
|
||||
return boost::shared_ptr<TProtocol>(headerProtocol);
|
||||
}
|
||||
|
||||
virtual boost::shared_ptr<TProtocol> getProtocol(
|
||||
boost::shared_ptr<transport::TTransport> inTrans,
|
||||
boost::shared_ptr<transport::TTransport> outTrans) {
|
||||
THeaderProtocol* headerProtocol = new THeaderProtocol(inTrans, outTrans, T_BINARY_PROTOCOL);
|
||||
return boost::shared_ptr<TProtocol>(headerProtocol);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::protocol
|
||||
|
||||
#endif // #ifndef THRIFT_PROTOCOL_THEADERPROTOCOL_H_
|
1099
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp
generated
vendored
Normal file
1099
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
324
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TJSONProtocol.h
generated
vendored
Normal file
324
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TJSONProtocol.h
generated
vendored
Normal file
|
@ -0,0 +1,324 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_PROTOCOL_TJSONPROTOCOL_H_
|
||||
#define _THRIFT_PROTOCOL_TJSONPROTOCOL_H_ 1
|
||||
|
||||
#include <thrift/protocol/TVirtualProtocol.h>
|
||||
|
||||
#include <stack>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace protocol {
|
||||
|
||||
// Forward declaration
|
||||
class TJSONContext;
|
||||
|
||||
/**
|
||||
* JSON protocol for Thrift.
|
||||
*
|
||||
* Implements a protocol which uses JSON as the wire-format.
|
||||
*
|
||||
* Thrift types are represented as described below:
|
||||
*
|
||||
* 1. Every Thrift integer type is represented as a JSON number.
|
||||
*
|
||||
* 2. Thrift doubles are represented as JSON numbers. Some special values are
|
||||
* represented as strings:
|
||||
* a. "NaN" for not-a-number values
|
||||
* b. "Infinity" for positive infinity
|
||||
* c. "-Infinity" for negative infinity
|
||||
*
|
||||
* 3. Thrift string values are emitted as JSON strings, with appropriate
|
||||
* escaping.
|
||||
*
|
||||
* 4. Thrift binary values are encoded into Base64 and emitted as JSON strings.
|
||||
* The readBinary() method is written such that it will properly skip if
|
||||
* called on a Thrift string (although it will decode garbage data).
|
||||
*
|
||||
* NOTE: Base64 padding is optional for Thrift binary value encoding. So
|
||||
* the readBinary() method needs to decode both input strings with padding
|
||||
* and those without one.
|
||||
*
|
||||
* 5. Thrift structs are represented as JSON objects, with the field ID as the
|
||||
* key, and the field value represented as a JSON object with a single
|
||||
* key-value pair. The key is a short string identifier for that type,
|
||||
* followed by the value. The valid type identifiers are: "tf" for bool,
|
||||
* "i8" for byte, "i16" for 16-bit integer, "i32" for 32-bit integer, "i64"
|
||||
* for 64-bit integer, "dbl" for double-precision loating point, "str" for
|
||||
* string (including binary), "rec" for struct ("records"), "map" for map,
|
||||
* "lst" for list, "set" for set.
|
||||
*
|
||||
* 6. Thrift lists and sets are represented as JSON arrays, with the first
|
||||
* element of the JSON array being the string identifier for the Thrift
|
||||
* element type and the second element of the JSON array being the count of
|
||||
* the Thrift elements. The Thrift elements then follow.
|
||||
*
|
||||
* 7. Thrift maps are represented as JSON arrays, with the first two elements
|
||||
* of the JSON array being the string identifiers for the Thrift key type
|
||||
* and value type, followed by the count of the Thrift pairs, followed by a
|
||||
* JSON object containing the key-value pairs. Note that JSON keys can only
|
||||
* be strings, which means that the key type of the Thrift map should be
|
||||
* restricted to numeric or string types -- in the case of numerics, they
|
||||
* are serialized as strings.
|
||||
*
|
||||
* 8. Thrift messages are represented as JSON arrays, with the protocol
|
||||
* version #, the message name, the message type, and the sequence ID as
|
||||
* the first 4 elements.
|
||||
*
|
||||
* More discussion of the double handling is probably warranted. The aim of
|
||||
* the current implementation is to match as closely as possible the behavior
|
||||
* of Java's Double.toString(), which has no precision loss. Implementors in
|
||||
* other languages should strive to achieve that where possible. I have not
|
||||
* yet verified whether boost:lexical_cast, which is doing that work for me in
|
||||
* C++, loses any precision, but I am leaving this as a future improvement. I
|
||||
* may try to provide a C component for this, so that other languages could
|
||||
* bind to the same underlying implementation for maximum consistency.
|
||||
*
|
||||
*/
|
||||
class TJSONProtocol : public TVirtualProtocol<TJSONProtocol> {
|
||||
public:
|
||||
TJSONProtocol(boost::shared_ptr<TTransport> ptrans);
|
||||
|
||||
~TJSONProtocol();
|
||||
|
||||
private:
|
||||
void pushContext(boost::shared_ptr<TJSONContext> c);
|
||||
|
||||
void popContext();
|
||||
|
||||
uint32_t writeJSONEscapeChar(uint8_t ch);
|
||||
|
||||
uint32_t writeJSONChar(uint8_t ch);
|
||||
|
||||
uint32_t writeJSONString(const std::string& str);
|
||||
|
||||
uint32_t writeJSONBase64(const std::string& str);
|
||||
|
||||
template <typename NumberType>
|
||||
uint32_t writeJSONInteger(NumberType num);
|
||||
|
||||
uint32_t writeJSONDouble(double num);
|
||||
|
||||
uint32_t writeJSONObjectStart();
|
||||
|
||||
uint32_t writeJSONObjectEnd();
|
||||
|
||||
uint32_t writeJSONArrayStart();
|
||||
|
||||
uint32_t writeJSONArrayEnd();
|
||||
|
||||
uint32_t readJSONSyntaxChar(uint8_t ch);
|
||||
|
||||
uint32_t readJSONEscapeChar(uint16_t* out);
|
||||
|
||||
uint32_t readJSONString(std::string& str, bool skipContext = false);
|
||||
|
||||
uint32_t readJSONBase64(std::string& str);
|
||||
|
||||
uint32_t readJSONNumericChars(std::string& str);
|
||||
|
||||
template <typename NumberType>
|
||||
uint32_t readJSONInteger(NumberType& num);
|
||||
|
||||
uint32_t readJSONDouble(double& num);
|
||||
|
||||
uint32_t readJSONObjectStart();
|
||||
|
||||
uint32_t readJSONObjectEnd();
|
||||
|
||||
uint32_t readJSONArrayStart();
|
||||
|
||||
uint32_t readJSONArrayEnd();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Writing functions.
|
||||
*/
|
||||
|
||||
uint32_t writeMessageBegin(const std::string& name,
|
||||
const TMessageType messageType,
|
||||
const int32_t seqid);
|
||||
|
||||
uint32_t writeMessageEnd();
|
||||
|
||||
uint32_t writeStructBegin(const char* name);
|
||||
|
||||
uint32_t writeStructEnd();
|
||||
|
||||
uint32_t writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId);
|
||||
|
||||
uint32_t writeFieldEnd();
|
||||
|
||||
uint32_t writeFieldStop();
|
||||
|
||||
uint32_t writeMapBegin(const TType keyType, const TType valType, const uint32_t size);
|
||||
|
||||
uint32_t writeMapEnd();
|
||||
|
||||
uint32_t writeListBegin(const TType elemType, const uint32_t size);
|
||||
|
||||
uint32_t writeListEnd();
|
||||
|
||||
uint32_t writeSetBegin(const TType elemType, const uint32_t size);
|
||||
|
||||
uint32_t writeSetEnd();
|
||||
|
||||
uint32_t writeBool(const bool value);
|
||||
|
||||
uint32_t writeByte(const int8_t byte);
|
||||
|
||||
uint32_t writeI16(const int16_t i16);
|
||||
|
||||
uint32_t writeI32(const int32_t i32);
|
||||
|
||||
uint32_t writeI64(const int64_t i64);
|
||||
|
||||
uint32_t writeDouble(const double dub);
|
||||
|
||||
uint32_t writeString(const std::string& str);
|
||||
|
||||
uint32_t writeBinary(const std::string& str);
|
||||
|
||||
/**
|
||||
* Reading functions
|
||||
*/
|
||||
|
||||
uint32_t readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqid);
|
||||
|
||||
uint32_t readMessageEnd();
|
||||
|
||||
uint32_t readStructBegin(std::string& name);
|
||||
|
||||
uint32_t readStructEnd();
|
||||
|
||||
uint32_t readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId);
|
||||
|
||||
uint32_t readFieldEnd();
|
||||
|
||||
uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size);
|
||||
|
||||
uint32_t readMapEnd();
|
||||
|
||||
uint32_t readListBegin(TType& elemType, uint32_t& size);
|
||||
|
||||
uint32_t readListEnd();
|
||||
|
||||
uint32_t readSetBegin(TType& elemType, uint32_t& size);
|
||||
|
||||
uint32_t readSetEnd();
|
||||
|
||||
uint32_t readBool(bool& value);
|
||||
|
||||
// Provide the default readBool() implementation for std::vector<bool>
|
||||
using TVirtualProtocol<TJSONProtocol>::readBool;
|
||||
|
||||
uint32_t readByte(int8_t& byte);
|
||||
|
||||
uint32_t readI16(int16_t& i16);
|
||||
|
||||
uint32_t readI32(int32_t& i32);
|
||||
|
||||
uint32_t readI64(int64_t& i64);
|
||||
|
||||
uint32_t readDouble(double& dub);
|
||||
|
||||
uint32_t readString(std::string& str);
|
||||
|
||||
uint32_t readBinary(std::string& str);
|
||||
|
||||
class LookaheadReader {
|
||||
|
||||
public:
|
||||
LookaheadReader(TTransport& trans) : trans_(&trans), hasData_(false) {}
|
||||
|
||||
uint8_t read() {
|
||||
if (hasData_) {
|
||||
hasData_ = false;
|
||||
} else {
|
||||
trans_->readAll(&data_, 1);
|
||||
}
|
||||
return data_;
|
||||
}
|
||||
|
||||
uint8_t peek() {
|
||||
if (!hasData_) {
|
||||
trans_->readAll(&data_, 1);
|
||||
}
|
||||
hasData_ = true;
|
||||
return data_;
|
||||
}
|
||||
|
||||
private:
|
||||
TTransport* trans_;
|
||||
bool hasData_;
|
||||
uint8_t data_;
|
||||
};
|
||||
|
||||
private:
|
||||
TTransport* trans_;
|
||||
|
||||
std::stack<boost::shared_ptr<TJSONContext> > contexts_;
|
||||
boost::shared_ptr<TJSONContext> context_;
|
||||
LookaheadReader reader_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs input and output protocol objects given transports.
|
||||
*/
|
||||
class TJSONProtocolFactory : public TProtocolFactory {
|
||||
public:
|
||||
TJSONProtocolFactory() {}
|
||||
|
||||
virtual ~TJSONProtocolFactory() {}
|
||||
|
||||
boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) {
|
||||
return boost::shared_ptr<TProtocol>(new TJSONProtocol(trans));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::protocol
|
||||
|
||||
// TODO(dreiss): Move part of ThriftJSONString into a .cpp file and remove this.
|
||||
#include <thrift/transport/TBufferTransports.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
|
||||
template <typename ThriftStruct>
|
||||
std::string ThriftJSONString(const ThriftStruct& ts) {
|
||||
using namespace apache::thrift::transport;
|
||||
using namespace apache::thrift::protocol;
|
||||
TMemoryBuffer* buffer = new TMemoryBuffer;
|
||||
boost::shared_ptr<TTransport> trans(buffer);
|
||||
TJSONProtocol protocol(trans);
|
||||
|
||||
ts.write(&protocol);
|
||||
|
||||
uint8_t* buf;
|
||||
uint32_t size;
|
||||
buffer->getBuffer(&buf, &size);
|
||||
return std::string((char*)buf, (unsigned int)size);
|
||||
}
|
||||
}
|
||||
} // apache::thrift
|
||||
|
||||
#endif // #define _THRIFT_PROTOCOL_TJSONPROTOCOL_H_ 1
|
40
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TMultiplexedProtocol.cpp
generated
vendored
Normal file
40
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TMultiplexedProtocol.cpp
generated
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/protocol/TMultiplexedProtocol.h>
|
||||
#include <thrift/processor/TMultiplexedProcessor.h>
|
||||
#include <thrift/protocol/TProtocolDecorator.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace protocol {
|
||||
uint32_t TMultiplexedProtocol::writeMessageBegin_virt(const std::string& _name,
|
||||
const TMessageType _type,
|
||||
const int32_t _seqid) {
|
||||
if (_type == T_CALL || _type == T_ONEWAY) {
|
||||
return TProtocolDecorator::writeMessageBegin_virt(serviceName + separator + _name,
|
||||
_type,
|
||||
_seqid);
|
||||
} else {
|
||||
return TProtocolDecorator::writeMessageBegin_virt(_name, _type, _seqid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
95
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TMultiplexedProtocol.h
generated
vendored
Normal file
95
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TMultiplexedProtocol.h
generated
vendored
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef THRIFT_TMULTIPLEXEDPROTOCOL_H_
|
||||
#define THRIFT_TMULTIPLEXEDPROTOCOL_H_ 1
|
||||
|
||||
#include <thrift/protocol/TProtocolDecorator.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace protocol {
|
||||
using boost::shared_ptr;
|
||||
|
||||
/**
|
||||
* <code>TMultiplexedProtocol</code> is a protocol-independent concrete decorator
|
||||
* that allows a Thrift client to communicate with a multiplexing Thrift server,
|
||||
* by prepending the service name to the function name during function calls.
|
||||
*
|
||||
* \note THIS IS NOT USED BY SERVERS. On the server, use
|
||||
* {@link apache::thrift::TMultiplexedProcessor TMultiplexedProcessor} to handle requests
|
||||
* from a multiplexing client.
|
||||
*
|
||||
* This example uses a single socket transport to invoke two services:
|
||||
*
|
||||
* <blockquote><code>
|
||||
* shared_ptr<TSocket> transport(new TSocket("localhost", 9090));
|
||||
* transport->open();
|
||||
*
|
||||
* shared_ptr<TBinaryProtocol> protocol(new TBinaryProtocol(transport));
|
||||
*
|
||||
* shared_ptr<TMultiplexedProtocol> mp1(new TMultiplexedProtocol(protocol, "Calculator"));
|
||||
* shared_ptr<CalculatorClient> service1(new CalculatorClient(mp1));
|
||||
*
|
||||
* shared_ptr<TMultiplexedProtocol> mp2(new TMultiplexedProtocol(protocol, "WeatherReport"));
|
||||
* shared_ptr<WeatherReportClient> service2(new WeatherReportClient(mp2));
|
||||
*
|
||||
* service1->add(2,2);
|
||||
* int temp = service2->getTemperature();
|
||||
* </code></blockquote>
|
||||
*
|
||||
* @see apache::thrift::protocol::TProtocolDecorator
|
||||
*/
|
||||
class TMultiplexedProtocol : public TProtocolDecorator {
|
||||
public:
|
||||
/**
|
||||
* Wrap the specified protocol, allowing it to be used to communicate with a
|
||||
* multiplexing server. The <code>serviceName</code> is required as it is
|
||||
* prepended to the message header so that the multiplexing server can broker
|
||||
* the function call to the proper service.
|
||||
*
|
||||
* \param _protocol Your communication protocol of choice, e.g. <code>TBinaryProtocol</code>.
|
||||
* \param _serviceName The service name of the service communicating via this protocol.
|
||||
*/
|
||||
TMultiplexedProtocol(shared_ptr<TProtocol> _protocol, const std::string& _serviceName)
|
||||
: TProtocolDecorator(_protocol), serviceName(_serviceName), separator(":") {}
|
||||
virtual ~TMultiplexedProtocol() {}
|
||||
|
||||
/**
|
||||
* Prepends the service name to the function name, separated by TMultiplexedProtocol::SEPARATOR.
|
||||
*
|
||||
* \param [in] _name The name of the method to be called in the service.
|
||||
* \param [in] _type The type of message
|
||||
* \param [in] _name The sequential id of the message
|
||||
*
|
||||
* \throws TException Passed through from wrapped <code>TProtocol</code> instance.
|
||||
*/
|
||||
uint32_t writeMessageBegin_virt(const std::string& _name,
|
||||
const TMessageType _type,
|
||||
const int32_t _seqid);
|
||||
|
||||
private:
|
||||
const std::string serviceName;
|
||||
const std::string separator;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // THRIFT_TMULTIPLEXEDPROTOCOL_H_
|
33
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TProtocol.cpp
generated
vendored
Normal file
33
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TProtocol.cpp
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/protocol/TProtocol.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace protocol {
|
||||
|
||||
TProtocol::~TProtocol() {}
|
||||
uint32_t TProtocol::skip_virt(TType type) {
|
||||
return ::apache::thrift::protocol::skip(*this, type);
|
||||
}
|
||||
|
||||
TProtocolFactory::~TProtocolFactory() {}
|
||||
|
||||
}}} // apache::thrift::protocol
|
762
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TProtocol.h
generated
vendored
Normal file
762
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TProtocol.h
generated
vendored
Normal file
|
@ -0,0 +1,762 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_PROTOCOL_TPROTOCOL_H_
|
||||
#define _THRIFT_PROTOCOL_TPROTOCOL_H_ 1
|
||||
|
||||
#ifdef _WIN32
|
||||
// Need to come before any Windows.h includes
|
||||
#include <Winsock2.h>
|
||||
#endif
|
||||
|
||||
#include <thrift/transport/TTransport.h>
|
||||
#include <thrift/protocol/TProtocolException.h>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <climits>
|
||||
|
||||
// Use this to get around strict aliasing rules.
|
||||
// For example, uint64_t i = bitwise_cast<uint64_t>(returns_double());
|
||||
// The most obvious implementation is to just cast a pointer,
|
||||
// but that doesn't work.
|
||||
// For a pretty in-depth explanation of the problem, see
|
||||
// http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html
|
||||
template <typename To, typename From>
|
||||
static inline To bitwise_cast(From from) {
|
||||
BOOST_STATIC_ASSERT(sizeof(From) == sizeof(To));
|
||||
|
||||
// BAD!!! These are all broken with -O2.
|
||||
//return *reinterpret_cast<To*>(&from); // BAD!!!
|
||||
//return *static_cast<To*>(static_cast<void*>(&from)); // BAD!!!
|
||||
//return *(To*)(void*)&from; // BAD!!!
|
||||
|
||||
// Super clean and paritally blessed by section 3.9 of the standard.
|
||||
//unsigned char c[sizeof(from)];
|
||||
//memcpy(c, &from, sizeof(from));
|
||||
//To to;
|
||||
//memcpy(&to, c, sizeof(c));
|
||||
//return to;
|
||||
|
||||
// Slightly more questionable.
|
||||
// Same code emitted by GCC.
|
||||
//To to;
|
||||
//memcpy(&to, &from, sizeof(from));
|
||||
//return to;
|
||||
|
||||
// Technically undefined, but almost universally supported,
|
||||
// and the most efficient implementation.
|
||||
union {
|
||||
From f;
|
||||
To t;
|
||||
} u;
|
||||
u.f = from;
|
||||
return u.t;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#ifndef __THRIFT_BYTE_ORDER
|
||||
# if defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
|
||||
# define __THRIFT_BYTE_ORDER BYTE_ORDER
|
||||
# define __THRIFT_LITTLE_ENDIAN LITTLE_ENDIAN
|
||||
# define __THRIFT_BIG_ENDIAN BIG_ENDIAN
|
||||
# else
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/detail/endian.hpp>
|
||||
# define __THRIFT_BYTE_ORDER BOOST_BYTE_ORDER
|
||||
# ifdef BOOST_LITTLE_ENDIAN
|
||||
# define __THRIFT_LITTLE_ENDIAN __THRIFT_BYTE_ORDER
|
||||
# define __THRIFT_BIG_ENDIAN 0
|
||||
# else
|
||||
# define __THRIFT_LITTLE_ENDIAN 0
|
||||
# define __THRIFT_BIG_ENDIAN __THRIFT_BYTE_ORDER
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if __THRIFT_BYTE_ORDER == __THRIFT_BIG_ENDIAN
|
||||
# if !defined(THRIFT_ntohll)
|
||||
# define THRIFT_ntohll(n) (n)
|
||||
# define THRIFT_htonll(n) (n)
|
||||
# endif
|
||||
# if defined(__GNUC__) && defined(__GLIBC__)
|
||||
# include <byteswap.h>
|
||||
# define THRIFT_htolell(n) bswap_64(n)
|
||||
# define THRIFT_letohll(n) bswap_64(n)
|
||||
# define THRIFT_htolel(n) bswap_32(n)
|
||||
# define THRIFT_letohl(n) bswap_32(n)
|
||||
# define THRIFT_htoles(n) bswap_16(n)
|
||||
# define THRIFT_letohs(n) bswap_16(n)
|
||||
# else /* GNUC & GLIBC */
|
||||
# define bswap_64(n) \
|
||||
( (((n) & 0xff00000000000000ull) >> 56) \
|
||||
| (((n) & 0x00ff000000000000ull) >> 40) \
|
||||
| (((n) & 0x0000ff0000000000ull) >> 24) \
|
||||
| (((n) & 0x000000ff00000000ull) >> 8) \
|
||||
| (((n) & 0x00000000ff000000ull) << 8) \
|
||||
| (((n) & 0x0000000000ff0000ull) << 24) \
|
||||
| (((n) & 0x000000000000ff00ull) << 40) \
|
||||
| (((n) & 0x00000000000000ffull) << 56) )
|
||||
# define bswap_32(n) \
|
||||
( (((n) & 0xff000000ul) >> 24) \
|
||||
| (((n) & 0x00ff0000ul) >> 8) \
|
||||
| (((n) & 0x0000ff00ul) << 8) \
|
||||
| (((n) & 0x000000fful) << 24) )
|
||||
# define bswap_16(n) \
|
||||
( (((n) & ((unsigned short)0xff00ul)) >> 8) \
|
||||
| (((n) & ((unsigned short)0x00fful)) << 8) )
|
||||
# define THRIFT_htolell(n) bswap_64(n)
|
||||
# define THRIFT_letohll(n) bswap_64(n)
|
||||
# define THRIFT_htolel(n) bswap_32(n)
|
||||
# define THRIFT_letohl(n) bswap_32(n)
|
||||
# define THRIFT_htoles(n) bswap_16(n)
|
||||
# define THRIFT_letohs(n) bswap_16(n)
|
||||
# endif /* GNUC & GLIBC */
|
||||
#elif __THRIFT_BYTE_ORDER == __THRIFT_LITTLE_ENDIAN
|
||||
# define THRIFT_htolell(n) (n)
|
||||
# define THRIFT_letohll(n) (n)
|
||||
# define THRIFT_htolel(n) (n)
|
||||
# define THRIFT_letohl(n) (n)
|
||||
# define THRIFT_htoles(n) (n)
|
||||
# define THRIFT_letohs(n) (n)
|
||||
# if defined(__GNUC__) && defined(__GLIBC__)
|
||||
# include <byteswap.h>
|
||||
# define THRIFT_ntohll(n) bswap_64(n)
|
||||
# define THRIFT_htonll(n) bswap_64(n)
|
||||
# elif defined(_MSC_VER) /* Microsoft Visual C++ */
|
||||
# define THRIFT_ntohll(n) ( _byteswap_uint64((uint64_t)n) )
|
||||
# define THRIFT_htonll(n) ( _byteswap_uint64((uint64_t)n) )
|
||||
# elif !defined(THRIFT_ntohll) /* Not GNUC/GLIBC or MSVC */
|
||||
# define THRIFT_ntohll(n) ( (((uint64_t)ntohl((uint32_t)n)) << 32) + ntohl((uint32_t)(n >> 32)) )
|
||||
# define THRIFT_htonll(n) ( (((uint64_t)htonl((uint32_t)n)) << 32) + htonl((uint32_t)(n >> 32)) )
|
||||
# endif /* GNUC/GLIBC or MSVC or something else */
|
||||
#else /* __THRIFT_BYTE_ORDER */
|
||||
# error "Can't define THRIFT_htonll or THRIFT_ntohll!"
|
||||
#endif
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace protocol {
|
||||
|
||||
using apache::thrift::transport::TTransport;
|
||||
|
||||
/**
|
||||
* Enumerated definition of the types that the Thrift protocol supports.
|
||||
* Take special note of the T_END type which is used specifically to mark
|
||||
* the end of a sequence of fields.
|
||||
*/
|
||||
enum TType {
|
||||
T_STOP = 0,
|
||||
T_VOID = 1,
|
||||
T_BOOL = 2,
|
||||
T_BYTE = 3,
|
||||
T_I08 = 3,
|
||||
T_I16 = 6,
|
||||
T_I32 = 8,
|
||||
T_U64 = 9,
|
||||
T_I64 = 10,
|
||||
T_DOUBLE = 4,
|
||||
T_STRING = 11,
|
||||
T_UTF7 = 11,
|
||||
T_STRUCT = 12,
|
||||
T_MAP = 13,
|
||||
T_SET = 14,
|
||||
T_LIST = 15,
|
||||
T_UTF8 = 16,
|
||||
T_UTF16 = 17
|
||||
};
|
||||
|
||||
/**
|
||||
* Enumerated definition of the message types that the Thrift protocol
|
||||
* supports.
|
||||
*/
|
||||
enum TMessageType {
|
||||
T_CALL = 1,
|
||||
T_REPLY = 2,
|
||||
T_EXCEPTION = 3,
|
||||
T_ONEWAY = 4
|
||||
};
|
||||
|
||||
static const uint32_t DEFAULT_RECURSION_LIMIT = 64;
|
||||
|
||||
/**
|
||||
* Abstract class for a thrift protocol driver. These are all the methods that
|
||||
* a protocol must implement. Essentially, there must be some way of reading
|
||||
* and writing all the base types, plus a mechanism for writing out structs
|
||||
* with indexed fields.
|
||||
*
|
||||
* TProtocol objects should not be shared across multiple encoding contexts,
|
||||
* as they may need to maintain internal state in some protocols (i.e. XML).
|
||||
* Note that is is acceptable for the TProtocol module to do its own internal
|
||||
* buffered reads/writes to the underlying TTransport where appropriate (i.e.
|
||||
* when parsing an input XML stream, reading should be batched rather than
|
||||
* looking ahead character by character for a close tag).
|
||||
*
|
||||
*/
|
||||
class TProtocol {
|
||||
public:
|
||||
virtual ~TProtocol();
|
||||
|
||||
/**
|
||||
* Writing functions.
|
||||
*/
|
||||
|
||||
virtual uint32_t writeMessageBegin_virt(const std::string& name,
|
||||
const TMessageType messageType,
|
||||
const int32_t seqid) = 0;
|
||||
|
||||
virtual uint32_t writeMessageEnd_virt() = 0;
|
||||
|
||||
virtual uint32_t writeStructBegin_virt(const char* name) = 0;
|
||||
|
||||
virtual uint32_t writeStructEnd_virt() = 0;
|
||||
|
||||
virtual uint32_t writeFieldBegin_virt(const char* name,
|
||||
const TType fieldType,
|
||||
const int16_t fieldId) = 0;
|
||||
|
||||
virtual uint32_t writeFieldEnd_virt() = 0;
|
||||
|
||||
virtual uint32_t writeFieldStop_virt() = 0;
|
||||
|
||||
virtual uint32_t writeMapBegin_virt(const TType keyType, const TType valType, const uint32_t size)
|
||||
= 0;
|
||||
|
||||
virtual uint32_t writeMapEnd_virt() = 0;
|
||||
|
||||
virtual uint32_t writeListBegin_virt(const TType elemType, const uint32_t size) = 0;
|
||||
|
||||
virtual uint32_t writeListEnd_virt() = 0;
|
||||
|
||||
virtual uint32_t writeSetBegin_virt(const TType elemType, const uint32_t size) = 0;
|
||||
|
||||
virtual uint32_t writeSetEnd_virt() = 0;
|
||||
|
||||
virtual uint32_t writeBool_virt(const bool value) = 0;
|
||||
|
||||
virtual uint32_t writeByte_virt(const int8_t byte) = 0;
|
||||
|
||||
virtual uint32_t writeI16_virt(const int16_t i16) = 0;
|
||||
|
||||
virtual uint32_t writeI32_virt(const int32_t i32) = 0;
|
||||
|
||||
virtual uint32_t writeI64_virt(const int64_t i64) = 0;
|
||||
|
||||
virtual uint32_t writeDouble_virt(const double dub) = 0;
|
||||
|
||||
virtual uint32_t writeString_virt(const std::string& str) = 0;
|
||||
|
||||
virtual uint32_t writeBinary_virt(const std::string& str) = 0;
|
||||
|
||||
uint32_t writeMessageBegin(const std::string& name,
|
||||
const TMessageType messageType,
|
||||
const int32_t seqid) {
|
||||
T_VIRTUAL_CALL();
|
||||
return writeMessageBegin_virt(name, messageType, seqid);
|
||||
}
|
||||
|
||||
uint32_t writeMessageEnd() {
|
||||
T_VIRTUAL_CALL();
|
||||
return writeMessageEnd_virt();
|
||||
}
|
||||
|
||||
uint32_t writeStructBegin(const char* name) {
|
||||
T_VIRTUAL_CALL();
|
||||
return writeStructBegin_virt(name);
|
||||
}
|
||||
|
||||
uint32_t writeStructEnd() {
|
||||
T_VIRTUAL_CALL();
|
||||
return writeStructEnd_virt();
|
||||
}
|
||||
|
||||
uint32_t writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId) {
|
||||
T_VIRTUAL_CALL();
|
||||
return writeFieldBegin_virt(name, fieldType, fieldId);
|
||||
}
|
||||
|
||||
uint32_t writeFieldEnd() {
|
||||
T_VIRTUAL_CALL();
|
||||
return writeFieldEnd_virt();
|
||||
}
|
||||
|
||||
uint32_t writeFieldStop() {
|
||||
T_VIRTUAL_CALL();
|
||||
return writeFieldStop_virt();
|
||||
}
|
||||
|
||||
uint32_t writeMapBegin(const TType keyType, const TType valType, const uint32_t size) {
|
||||
T_VIRTUAL_CALL();
|
||||
return writeMapBegin_virt(keyType, valType, size);
|
||||
}
|
||||
|
||||
uint32_t writeMapEnd() {
|
||||
T_VIRTUAL_CALL();
|
||||
return writeMapEnd_virt();
|
||||
}
|
||||
|
||||
uint32_t writeListBegin(const TType elemType, const uint32_t size) {
|
||||
T_VIRTUAL_CALL();
|
||||
return writeListBegin_virt(elemType, size);
|
||||
}
|
||||
|
||||
uint32_t writeListEnd() {
|
||||
T_VIRTUAL_CALL();
|
||||
return writeListEnd_virt();
|
||||
}
|
||||
|
||||
uint32_t writeSetBegin(const TType elemType, const uint32_t size) {
|
||||
T_VIRTUAL_CALL();
|
||||
return writeSetBegin_virt(elemType, size);
|
||||
}
|
||||
|
||||
uint32_t writeSetEnd() {
|
||||
T_VIRTUAL_CALL();
|
||||
return writeSetEnd_virt();
|
||||
}
|
||||
|
||||
uint32_t writeBool(const bool value) {
|
||||
T_VIRTUAL_CALL();
|
||||
return writeBool_virt(value);
|
||||
}
|
||||
|
||||
uint32_t writeByte(const int8_t byte) {
|
||||
T_VIRTUAL_CALL();
|
||||
return writeByte_virt(byte);
|
||||
}
|
||||
|
||||
uint32_t writeI16(const int16_t i16) {
|
||||
T_VIRTUAL_CALL();
|
||||
return writeI16_virt(i16);
|
||||
}
|
||||
|
||||
uint32_t writeI32(const int32_t i32) {
|
||||
T_VIRTUAL_CALL();
|
||||
return writeI32_virt(i32);
|
||||
}
|
||||
|
||||
uint32_t writeI64(const int64_t i64) {
|
||||
T_VIRTUAL_CALL();
|
||||
return writeI64_virt(i64);
|
||||
}
|
||||
|
||||
uint32_t writeDouble(const double dub) {
|
||||
T_VIRTUAL_CALL();
|
||||
return writeDouble_virt(dub);
|
||||
}
|
||||
|
||||
uint32_t writeString(const std::string& str) {
|
||||
T_VIRTUAL_CALL();
|
||||
return writeString_virt(str);
|
||||
}
|
||||
|
||||
uint32_t writeBinary(const std::string& str) {
|
||||
T_VIRTUAL_CALL();
|
||||
return writeBinary_virt(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reading functions
|
||||
*/
|
||||
|
||||
virtual uint32_t readMessageBegin_virt(std::string& name,
|
||||
TMessageType& messageType,
|
||||
int32_t& seqid) = 0;
|
||||
|
||||
virtual uint32_t readMessageEnd_virt() = 0;
|
||||
|
||||
virtual uint32_t readStructBegin_virt(std::string& name) = 0;
|
||||
|
||||
virtual uint32_t readStructEnd_virt() = 0;
|
||||
|
||||
virtual uint32_t readFieldBegin_virt(std::string& name, TType& fieldType, int16_t& fieldId) = 0;
|
||||
|
||||
virtual uint32_t readFieldEnd_virt() = 0;
|
||||
|
||||
virtual uint32_t readMapBegin_virt(TType& keyType, TType& valType, uint32_t& size) = 0;
|
||||
|
||||
virtual uint32_t readMapEnd_virt() = 0;
|
||||
|
||||
virtual uint32_t readListBegin_virt(TType& elemType, uint32_t& size) = 0;
|
||||
|
||||
virtual uint32_t readListEnd_virt() = 0;
|
||||
|
||||
virtual uint32_t readSetBegin_virt(TType& elemType, uint32_t& size) = 0;
|
||||
|
||||
virtual uint32_t readSetEnd_virt() = 0;
|
||||
|
||||
virtual uint32_t readBool_virt(bool& value) = 0;
|
||||
|
||||
virtual uint32_t readBool_virt(std::vector<bool>::reference value) = 0;
|
||||
|
||||
virtual uint32_t readByte_virt(int8_t& byte) = 0;
|
||||
|
||||
virtual uint32_t readI16_virt(int16_t& i16) = 0;
|
||||
|
||||
virtual uint32_t readI32_virt(int32_t& i32) = 0;
|
||||
|
||||
virtual uint32_t readI64_virt(int64_t& i64) = 0;
|
||||
|
||||
virtual uint32_t readDouble_virt(double& dub) = 0;
|
||||
|
||||
virtual uint32_t readString_virt(std::string& str) = 0;
|
||||
|
||||
virtual uint32_t readBinary_virt(std::string& str) = 0;
|
||||
|
||||
uint32_t readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqid) {
|
||||
T_VIRTUAL_CALL();
|
||||
return readMessageBegin_virt(name, messageType, seqid);
|
||||
}
|
||||
|
||||
uint32_t readMessageEnd() {
|
||||
T_VIRTUAL_CALL();
|
||||
return readMessageEnd_virt();
|
||||
}
|
||||
|
||||
uint32_t readStructBegin(std::string& name) {
|
||||
T_VIRTUAL_CALL();
|
||||
return readStructBegin_virt(name);
|
||||
}
|
||||
|
||||
uint32_t readStructEnd() {
|
||||
T_VIRTUAL_CALL();
|
||||
return readStructEnd_virt();
|
||||
}
|
||||
|
||||
uint32_t readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId) {
|
||||
T_VIRTUAL_CALL();
|
||||
return readFieldBegin_virt(name, fieldType, fieldId);
|
||||
}
|
||||
|
||||
uint32_t readFieldEnd() {
|
||||
T_VIRTUAL_CALL();
|
||||
return readFieldEnd_virt();
|
||||
}
|
||||
|
||||
uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size) {
|
||||
T_VIRTUAL_CALL();
|
||||
return readMapBegin_virt(keyType, valType, size);
|
||||
}
|
||||
|
||||
uint32_t readMapEnd() {
|
||||
T_VIRTUAL_CALL();
|
||||
return readMapEnd_virt();
|
||||
}
|
||||
|
||||
uint32_t readListBegin(TType& elemType, uint32_t& size) {
|
||||
T_VIRTUAL_CALL();
|
||||
return readListBegin_virt(elemType, size);
|
||||
}
|
||||
|
||||
uint32_t readListEnd() {
|
||||
T_VIRTUAL_CALL();
|
||||
return readListEnd_virt();
|
||||
}
|
||||
|
||||
uint32_t readSetBegin(TType& elemType, uint32_t& size) {
|
||||
T_VIRTUAL_CALL();
|
||||
return readSetBegin_virt(elemType, size);
|
||||
}
|
||||
|
||||
uint32_t readSetEnd() {
|
||||
T_VIRTUAL_CALL();
|
||||
return readSetEnd_virt();
|
||||
}
|
||||
|
||||
uint32_t readBool(bool& value) {
|
||||
T_VIRTUAL_CALL();
|
||||
return readBool_virt(value);
|
||||
}
|
||||
|
||||
uint32_t readByte(int8_t& byte) {
|
||||
T_VIRTUAL_CALL();
|
||||
return readByte_virt(byte);
|
||||
}
|
||||
|
||||
uint32_t readI16(int16_t& i16) {
|
||||
T_VIRTUAL_CALL();
|
||||
return readI16_virt(i16);
|
||||
}
|
||||
|
||||
uint32_t readI32(int32_t& i32) {
|
||||
T_VIRTUAL_CALL();
|
||||
return readI32_virt(i32);
|
||||
}
|
||||
|
||||
uint32_t readI64(int64_t& i64) {
|
||||
T_VIRTUAL_CALL();
|
||||
return readI64_virt(i64);
|
||||
}
|
||||
|
||||
uint32_t readDouble(double& dub) {
|
||||
T_VIRTUAL_CALL();
|
||||
return readDouble_virt(dub);
|
||||
}
|
||||
|
||||
uint32_t readString(std::string& str) {
|
||||
T_VIRTUAL_CALL();
|
||||
return readString_virt(str);
|
||||
}
|
||||
|
||||
uint32_t readBinary(std::string& str) {
|
||||
T_VIRTUAL_CALL();
|
||||
return readBinary_virt(str);
|
||||
}
|
||||
|
||||
/*
|
||||
* std::vector is specialized for bool, and its elements are individual bits
|
||||
* rather than bools. We need to define a different version of readBool()
|
||||
* to work with std::vector<bool>.
|
||||
*/
|
||||
uint32_t readBool(std::vector<bool>::reference value) {
|
||||
T_VIRTUAL_CALL();
|
||||
return readBool_virt(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to arbitrarily skip over data.
|
||||
*/
|
||||
uint32_t skip(TType type) {
|
||||
T_VIRTUAL_CALL();
|
||||
return skip_virt(type);
|
||||
}
|
||||
virtual uint32_t skip_virt(TType type);
|
||||
|
||||
inline boost::shared_ptr<TTransport> getTransport() { return ptrans_; }
|
||||
|
||||
// TODO: remove these two calls, they are for backwards
|
||||
// compatibility
|
||||
inline boost::shared_ptr<TTransport> getInputTransport() { return ptrans_; }
|
||||
inline boost::shared_ptr<TTransport> getOutputTransport() { return ptrans_; }
|
||||
|
||||
// input and output recursion depth are kept separate so that one protocol
|
||||
// can be used concurrently for both input and output.
|
||||
void incrementInputRecursionDepth() {
|
||||
if (recursion_limit_ < ++input_recursion_depth_) {
|
||||
throw TProtocolException(TProtocolException::DEPTH_LIMIT);
|
||||
}
|
||||
}
|
||||
void decrementInputRecursionDepth() { --input_recursion_depth_; }
|
||||
|
||||
void incrementOutputRecursionDepth() {
|
||||
if (recursion_limit_ < ++output_recursion_depth_) {
|
||||
throw TProtocolException(TProtocolException::DEPTH_LIMIT);
|
||||
}
|
||||
}
|
||||
void decrementOutputRecursionDepth() { --output_recursion_depth_; }
|
||||
|
||||
uint32_t getRecursionLimit() const {return recursion_limit_;}
|
||||
void setRecurisionLimit(uint32_t depth) {recursion_limit_ = depth;}
|
||||
|
||||
protected:
|
||||
TProtocol(boost::shared_ptr<TTransport> ptrans)
|
||||
: ptrans_(ptrans), input_recursion_depth_(0), output_recursion_depth_(0), recursion_limit_(DEFAULT_RECURSION_LIMIT)
|
||||
{}
|
||||
|
||||
boost::shared_ptr<TTransport> ptrans_;
|
||||
|
||||
private:
|
||||
TProtocol() {}
|
||||
uint32_t input_recursion_depth_;
|
||||
uint32_t output_recursion_depth_;
|
||||
uint32_t recursion_limit_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs input and output protocol objects given transports.
|
||||
*/
|
||||
class TProtocolFactory {
|
||||
public:
|
||||
TProtocolFactory() {}
|
||||
|
||||
virtual ~TProtocolFactory();
|
||||
|
||||
virtual boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) = 0;
|
||||
virtual boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> inTrans,
|
||||
boost::shared_ptr<TTransport> outTrans) {
|
||||
(void)outTrans;
|
||||
return getProtocol(inTrans);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Dummy protocol class.
|
||||
*
|
||||
* This class does nothing, and should never be instantiated.
|
||||
* It is used only by the generator code.
|
||||
*/
|
||||
class TDummyProtocol : public TProtocol {};
|
||||
|
||||
// This is the default / legacy choice
|
||||
struct TNetworkBigEndian
|
||||
{
|
||||
static uint16_t toWire16(uint16_t x) {return htons(x);}
|
||||
static uint32_t toWire32(uint32_t x) {return htonl(x);}
|
||||
static uint64_t toWire64(uint64_t x) {return THRIFT_htonll(x);}
|
||||
static uint16_t fromWire16(uint16_t x) {return ntohs(x);}
|
||||
static uint32_t fromWire32(uint32_t x) {return ntohl(x);}
|
||||
static uint64_t fromWire64(uint64_t x) {return THRIFT_ntohll(x);}
|
||||
};
|
||||
|
||||
// On most systems, this will be a bit faster than TNetworkBigEndian
|
||||
struct TNetworkLittleEndian
|
||||
{
|
||||
static uint16_t toWire16(uint16_t x) {return THRIFT_htoles(x);}
|
||||
static uint32_t toWire32(uint32_t x) {return THRIFT_htolel(x);}
|
||||
static uint64_t toWire64(uint64_t x) {return THRIFT_htolell(x);}
|
||||
static uint16_t fromWire16(uint16_t x) {return THRIFT_letohs(x);}
|
||||
static uint32_t fromWire32(uint32_t x) {return THRIFT_letohl(x);}
|
||||
static uint64_t fromWire64(uint64_t x) {return THRIFT_letohll(x);}
|
||||
};
|
||||
|
||||
struct TOutputRecursionTracker {
|
||||
TProtocol &prot_;
|
||||
TOutputRecursionTracker(TProtocol &prot) : prot_(prot) {
|
||||
prot_.incrementOutputRecursionDepth();
|
||||
}
|
||||
~TOutputRecursionTracker() {
|
||||
prot_.decrementOutputRecursionDepth();
|
||||
}
|
||||
};
|
||||
|
||||
struct TInputRecursionTracker {
|
||||
TProtocol &prot_;
|
||||
TInputRecursionTracker(TProtocol &prot) : prot_(prot) {
|
||||
prot_.incrementInputRecursionDepth();
|
||||
}
|
||||
~TInputRecursionTracker() {
|
||||
prot_.decrementInputRecursionDepth();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper template for implementing TProtocol::skip().
|
||||
*
|
||||
* Templatized to avoid having to make virtual function calls.
|
||||
*/
|
||||
template <class Protocol_>
|
||||
uint32_t skip(Protocol_& prot, TType type) {
|
||||
TInputRecursionTracker tracker(prot);
|
||||
|
||||
switch (type) {
|
||||
case T_BOOL: {
|
||||
bool boolv;
|
||||
return prot.readBool(boolv);
|
||||
}
|
||||
case T_BYTE: {
|
||||
int8_t bytev;
|
||||
return prot.readByte(bytev);
|
||||
}
|
||||
case T_I16: {
|
||||
int16_t i16;
|
||||
return prot.readI16(i16);
|
||||
}
|
||||
case T_I32: {
|
||||
int32_t i32;
|
||||
return prot.readI32(i32);
|
||||
}
|
||||
case T_I64: {
|
||||
int64_t i64;
|
||||
return prot.readI64(i64);
|
||||
}
|
||||
case T_DOUBLE: {
|
||||
double dub;
|
||||
return prot.readDouble(dub);
|
||||
}
|
||||
case T_STRING: {
|
||||
std::string str;
|
||||
return prot.readBinary(str);
|
||||
}
|
||||
case T_STRUCT: {
|
||||
uint32_t result = 0;
|
||||
std::string name;
|
||||
int16_t fid;
|
||||
TType ftype;
|
||||
result += prot.readStructBegin(name);
|
||||
while (true) {
|
||||
result += prot.readFieldBegin(name, ftype, fid);
|
||||
if (ftype == T_STOP) {
|
||||
break;
|
||||
}
|
||||
result += skip(prot, ftype);
|
||||
result += prot.readFieldEnd();
|
||||
}
|
||||
result += prot.readStructEnd();
|
||||
return result;
|
||||
}
|
||||
case T_MAP: {
|
||||
uint32_t result = 0;
|
||||
TType keyType;
|
||||
TType valType;
|
||||
uint32_t i, size;
|
||||
result += prot.readMapBegin(keyType, valType, size);
|
||||
for (i = 0; i < size; i++) {
|
||||
result += skip(prot, keyType);
|
||||
result += skip(prot, valType);
|
||||
}
|
||||
result += prot.readMapEnd();
|
||||
return result;
|
||||
}
|
||||
case T_SET: {
|
||||
uint32_t result = 0;
|
||||
TType elemType;
|
||||
uint32_t i, size;
|
||||
result += prot.readSetBegin(elemType, size);
|
||||
for (i = 0; i < size; i++) {
|
||||
result += skip(prot, elemType);
|
||||
}
|
||||
result += prot.readSetEnd();
|
||||
return result;
|
||||
}
|
||||
case T_LIST: {
|
||||
uint32_t result = 0;
|
||||
TType elemType;
|
||||
uint32_t i, size;
|
||||
result += prot.readListBegin(elemType, size);
|
||||
for (i = 0; i < size; i++) {
|
||||
result += skip(prot, elemType);
|
||||
}
|
||||
result += prot.readListEnd();
|
||||
return result;
|
||||
}
|
||||
case T_STOP:
|
||||
case T_VOID:
|
||||
case T_U64:
|
||||
case T_UTF8:
|
||||
case T_UTF16:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}}} // apache::thrift::protocol
|
||||
|
||||
#endif // #define _THRIFT_PROTOCOL_TPROTOCOL_H_ 1
|
151
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TProtocolDecorator.h
generated
vendored
Normal file
151
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TProtocolDecorator.h
generated
vendored
Normal file
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef THRIFT_TPROTOCOLDECORATOR_H_
|
||||
#define THRIFT_TPROTOCOLDECORATOR_H_ 1
|
||||
|
||||
#include <thrift/protocol/TProtocol.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace protocol {
|
||||
using boost::shared_ptr;
|
||||
|
||||
/**
|
||||
* <code>TProtocolDecorator</code> forwards all requests to an enclosed
|
||||
* <code>TProtocol</code> instance, providing a way to author concise
|
||||
* concrete decorator subclasses.
|
||||
*
|
||||
* <p>See p.175 of Design Patterns (by Gamma et al.)</p>
|
||||
*
|
||||
* @see apache::thrift::protocol::TMultiplexedProtocol
|
||||
*/
|
||||
class TProtocolDecorator : public TProtocol {
|
||||
public:
|
||||
virtual ~TProtocolDecorator() {}
|
||||
|
||||
// Desc: Initializes the protocol decorator object.
|
||||
TProtocolDecorator(shared_ptr<TProtocol> proto)
|
||||
: TProtocol(proto->getTransport()), protocol(proto) {}
|
||||
|
||||
virtual uint32_t writeMessageBegin_virt(const std::string& name,
|
||||
const TMessageType messageType,
|
||||
const int32_t seqid) {
|
||||
return protocol->writeMessageBegin(name, messageType, seqid);
|
||||
}
|
||||
virtual uint32_t writeMessageEnd_virt() { return protocol->writeMessageEnd(); }
|
||||
virtual uint32_t writeStructBegin_virt(const char* name) {
|
||||
return protocol->writeStructBegin(name);
|
||||
}
|
||||
virtual uint32_t writeStructEnd_virt() { return protocol->writeStructEnd(); }
|
||||
|
||||
virtual uint32_t writeFieldBegin_virt(const char* name,
|
||||
const TType fieldType,
|
||||
const int16_t fieldId) {
|
||||
return protocol->writeFieldBegin(name, fieldType, fieldId);
|
||||
}
|
||||
|
||||
virtual uint32_t writeFieldEnd_virt() { return protocol->writeFieldEnd(); }
|
||||
virtual uint32_t writeFieldStop_virt() { return protocol->writeFieldStop(); }
|
||||
|
||||
virtual uint32_t writeMapBegin_virt(const TType keyType,
|
||||
const TType valType,
|
||||
const uint32_t size) {
|
||||
return protocol->writeMapBegin(keyType, valType, size);
|
||||
}
|
||||
|
||||
virtual uint32_t writeMapEnd_virt() { return protocol->writeMapEnd(); }
|
||||
|
||||
virtual uint32_t writeListBegin_virt(const TType elemType, const uint32_t size) {
|
||||
return protocol->writeListBegin(elemType, size);
|
||||
}
|
||||
virtual uint32_t writeListEnd_virt() { return protocol->writeListEnd(); }
|
||||
|
||||
virtual uint32_t writeSetBegin_virt(const TType elemType, const uint32_t size) {
|
||||
return protocol->writeSetBegin(elemType, size);
|
||||
}
|
||||
virtual uint32_t writeSetEnd_virt() { return protocol->writeSetEnd(); }
|
||||
|
||||
virtual uint32_t writeBool_virt(const bool value) { return protocol->writeBool(value); }
|
||||
virtual uint32_t writeByte_virt(const int8_t byte) { return protocol->writeByte(byte); }
|
||||
virtual uint32_t writeI16_virt(const int16_t i16) { return protocol->writeI16(i16); }
|
||||
virtual uint32_t writeI32_virt(const int32_t i32) { return protocol->writeI32(i32); }
|
||||
virtual uint32_t writeI64_virt(const int64_t i64) { return protocol->writeI64(i64); }
|
||||
|
||||
virtual uint32_t writeDouble_virt(const double dub) { return protocol->writeDouble(dub); }
|
||||
virtual uint32_t writeString_virt(const std::string& str) { return protocol->writeString(str); }
|
||||
virtual uint32_t writeBinary_virt(const std::string& str) { return protocol->writeBinary(str); }
|
||||
|
||||
virtual uint32_t readMessageBegin_virt(std::string& name,
|
||||
TMessageType& messageType,
|
||||
int32_t& seqid) {
|
||||
return protocol->readMessageBegin(name, messageType, seqid);
|
||||
}
|
||||
virtual uint32_t readMessageEnd_virt() { return protocol->readMessageEnd(); }
|
||||
|
||||
virtual uint32_t readStructBegin_virt(std::string& name) {
|
||||
return protocol->readStructBegin(name);
|
||||
}
|
||||
virtual uint32_t readStructEnd_virt() { return protocol->readStructEnd(); }
|
||||
|
||||
virtual uint32_t readFieldBegin_virt(std::string& name, TType& fieldType, int16_t& fieldId) {
|
||||
return protocol->readFieldBegin(name, fieldType, fieldId);
|
||||
}
|
||||
virtual uint32_t readFieldEnd_virt() { return protocol->readFieldEnd(); }
|
||||
|
||||
virtual uint32_t readMapBegin_virt(TType& keyType, TType& valType, uint32_t& size) {
|
||||
return protocol->readMapBegin(keyType, valType, size);
|
||||
}
|
||||
virtual uint32_t readMapEnd_virt() { return protocol->readMapEnd(); }
|
||||
|
||||
virtual uint32_t readListBegin_virt(TType& elemType, uint32_t& size) {
|
||||
return protocol->readListBegin(elemType, size);
|
||||
}
|
||||
virtual uint32_t readListEnd_virt() { return protocol->readListEnd(); }
|
||||
|
||||
virtual uint32_t readSetBegin_virt(TType& elemType, uint32_t& size) {
|
||||
return protocol->readSetBegin(elemType, size);
|
||||
}
|
||||
virtual uint32_t readSetEnd_virt() { return protocol->readSetEnd(); }
|
||||
|
||||
virtual uint32_t readBool_virt(bool& value) { return protocol->readBool(value); }
|
||||
virtual uint32_t readBool_virt(std::vector<bool>::reference value) {
|
||||
return protocol->readBool(value);
|
||||
}
|
||||
|
||||
virtual uint32_t readByte_virt(int8_t& byte) { return protocol->readByte(byte); }
|
||||
|
||||
virtual uint32_t readI16_virt(int16_t& i16) { return protocol->readI16(i16); }
|
||||
virtual uint32_t readI32_virt(int32_t& i32) { return protocol->readI32(i32); }
|
||||
virtual uint32_t readI64_virt(int64_t& i64) { return protocol->readI64(i64); }
|
||||
|
||||
virtual uint32_t readDouble_virt(double& dub) { return protocol->readDouble(dub); }
|
||||
|
||||
virtual uint32_t readString_virt(std::string& str) { return protocol->readString(str); }
|
||||
virtual uint32_t readBinary_virt(std::string& str) { return protocol->readBinary(str); }
|
||||
|
||||
private:
|
||||
shared_ptr<TProtocol> protocol;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // THRIFT_TPROTOCOLDECORATOR_H_
|
105
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TProtocolException.h
generated
vendored
Normal file
105
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TProtocolException.h
generated
vendored
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_PROTOCOL_TPROTOCOLEXCEPTION_H_
|
||||
#define _THRIFT_PROTOCOL_TPROTOCOLEXCEPTION_H_ 1
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace protocol {
|
||||
|
||||
/**
|
||||
* Class to encapsulate all the possible types of protocol errors that may
|
||||
* occur in various protocol systems. This provides a sort of generic
|
||||
* wrapper around the vague UNIX E_ error codes that lets a common code
|
||||
* base of error handling to be used for various types of protocols, i.e.
|
||||
* pipes etc.
|
||||
*
|
||||
*/
|
||||
class TProtocolException : public apache::thrift::TException {
|
||||
public:
|
||||
/**
|
||||
* Error codes for the various types of exceptions.
|
||||
*/
|
||||
enum TProtocolExceptionType {
|
||||
UNKNOWN = 0,
|
||||
INVALID_DATA = 1,
|
||||
NEGATIVE_SIZE = 2,
|
||||
SIZE_LIMIT = 3,
|
||||
BAD_VERSION = 4,
|
||||
NOT_IMPLEMENTED = 5,
|
||||
DEPTH_LIMIT = 6
|
||||
};
|
||||
|
||||
TProtocolException() : apache::thrift::TException(), type_(UNKNOWN) {}
|
||||
|
||||
TProtocolException(TProtocolExceptionType type) : apache::thrift::TException(), type_(type) {}
|
||||
|
||||
TProtocolException(const std::string& message)
|
||||
: apache::thrift::TException(message), type_(UNKNOWN) {}
|
||||
|
||||
TProtocolException(TProtocolExceptionType type, const std::string& message)
|
||||
: apache::thrift::TException(message), type_(type) {}
|
||||
|
||||
virtual ~TProtocolException() throw() {}
|
||||
|
||||
/**
|
||||
* Returns an error code that provides information about the type of error
|
||||
* that has occurred.
|
||||
*
|
||||
* @return Error code
|
||||
*/
|
||||
TProtocolExceptionType getType() const { return type_; }
|
||||
|
||||
virtual const char* what() const throw() {
|
||||
if (message_.empty()) {
|
||||
switch (type_) {
|
||||
case UNKNOWN:
|
||||
return "TProtocolException: Unknown protocol exception";
|
||||
case INVALID_DATA:
|
||||
return "TProtocolException: Invalid data";
|
||||
case NEGATIVE_SIZE:
|
||||
return "TProtocolException: Negative size";
|
||||
case SIZE_LIMIT:
|
||||
return "TProtocolException: Exceeded size limit";
|
||||
case BAD_VERSION:
|
||||
return "TProtocolException: Invalid version";
|
||||
case NOT_IMPLEMENTED:
|
||||
return "TProtocolException: Not implemented";
|
||||
default:
|
||||
return "TProtocolException: (Invalid exception type)";
|
||||
}
|
||||
} else {
|
||||
return message_.c_str();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Error code
|
||||
*/
|
||||
TProtocolExceptionType type_;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::protocol
|
||||
|
||||
#endif // #ifndef _THRIFT_PROTOCOL_TPROTOCOLEXCEPTION_H_
|
177
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TProtocolTap.h
generated
vendored
Normal file
177
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TProtocolTap.h
generated
vendored
Normal file
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_PROTOCOL_TPROTOCOLTAP_H_
|
||||
#define _THRIFT_PROTOCOL_TPROTOCOLTAP_H_ 1
|
||||
|
||||
#include <thrift/protocol/TVirtualProtocol.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace protocol {
|
||||
|
||||
using apache::thrift::transport::TTransport;
|
||||
|
||||
/**
|
||||
* Puts a wiretap on a protocol object. Any reads to this class are passed
|
||||
* through to an enclosed protocol object, but also mirrored as write to a
|
||||
* second protocol object.
|
||||
*
|
||||
*/
|
||||
class TProtocolTap : public TVirtualProtocol<TProtocolTap> {
|
||||
public:
|
||||
TProtocolTap(boost::shared_ptr<TProtocol> source, boost::shared_ptr<TProtocol> sink)
|
||||
: TVirtualProtocol<TProtocolTap>(source->getTransport()), source_(source), sink_(sink) {}
|
||||
|
||||
uint32_t readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqid) {
|
||||
uint32_t rv = source_->readMessageBegin(name, messageType, seqid);
|
||||
sink_->writeMessageBegin(name, messageType, seqid);
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint32_t readMessageEnd() {
|
||||
uint32_t rv = source_->readMessageEnd();
|
||||
sink_->writeMessageEnd();
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint32_t readStructBegin(std::string& name) {
|
||||
uint32_t rv = source_->readStructBegin(name);
|
||||
sink_->writeStructBegin(name.c_str());
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint32_t readStructEnd() {
|
||||
uint32_t rv = source_->readStructEnd();
|
||||
sink_->writeStructEnd();
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint32_t readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId) {
|
||||
uint32_t rv = source_->readFieldBegin(name, fieldType, fieldId);
|
||||
if (fieldType == T_STOP) {
|
||||
sink_->writeFieldStop();
|
||||
} else {
|
||||
sink_->writeFieldBegin(name.c_str(), fieldType, fieldId);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint32_t readFieldEnd() {
|
||||
uint32_t rv = source_->readFieldEnd();
|
||||
sink_->writeFieldEnd();
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size) {
|
||||
uint32_t rv = source_->readMapBegin(keyType, valType, size);
|
||||
sink_->writeMapBegin(keyType, valType, size);
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint32_t readMapEnd() {
|
||||
uint32_t rv = source_->readMapEnd();
|
||||
sink_->writeMapEnd();
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint32_t readListBegin(TType& elemType, uint32_t& size) {
|
||||
uint32_t rv = source_->readListBegin(elemType, size);
|
||||
sink_->writeListBegin(elemType, size);
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint32_t readListEnd() {
|
||||
uint32_t rv = source_->readListEnd();
|
||||
sink_->writeListEnd();
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint32_t readSetBegin(TType& elemType, uint32_t& size) {
|
||||
uint32_t rv = source_->readSetBegin(elemType, size);
|
||||
sink_->writeSetBegin(elemType, size);
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint32_t readSetEnd() {
|
||||
uint32_t rv = source_->readSetEnd();
|
||||
sink_->writeSetEnd();
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint32_t readBool(bool& value) {
|
||||
uint32_t rv = source_->readBool(value);
|
||||
sink_->writeBool(value);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Provide the default readBool() implementation for std::vector<bool>
|
||||
using TVirtualProtocol<TProtocolTap>::readBool;
|
||||
|
||||
uint32_t readByte(int8_t& byte) {
|
||||
uint32_t rv = source_->readByte(byte);
|
||||
sink_->writeByte(byte);
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint32_t readI16(int16_t& i16) {
|
||||
uint32_t rv = source_->readI16(i16);
|
||||
sink_->writeI16(i16);
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint32_t readI32(int32_t& i32) {
|
||||
uint32_t rv = source_->readI32(i32);
|
||||
sink_->writeI32(i32);
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint32_t readI64(int64_t& i64) {
|
||||
uint32_t rv = source_->readI64(i64);
|
||||
sink_->writeI64(i64);
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint32_t readDouble(double& dub) {
|
||||
uint32_t rv = source_->readDouble(dub);
|
||||
sink_->writeDouble(dub);
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint32_t readString(std::string& str) {
|
||||
uint32_t rv = source_->readString(str);
|
||||
sink_->writeString(str);
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint32_t readBinary(std::string& str) {
|
||||
uint32_t rv = source_->readBinary(str);
|
||||
sink_->writeBinary(str);
|
||||
return rv;
|
||||
}
|
||||
|
||||
private:
|
||||
boost::shared_ptr<TProtocol> source_;
|
||||
boost::shared_ptr<TProtocol> sink_;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::protocol
|
||||
|
||||
#endif // #define _THRIFT_PROTOCOL_TPROTOCOLTAP_H_ 1
|
36
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TProtocolTypes.h
generated
vendored
Normal file
36
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TProtocolTypes.h
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef THRIFT_PROTOCOL_TPROTOCOLTYPES_H_
|
||||
#define THRIFT_PROTOCOL_TPROTOCOLTYPES_H_ 1
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace protocol {
|
||||
|
||||
enum PROTOCOL_TYPES {
|
||||
T_BINARY_PROTOCOL = 0,
|
||||
T_JSON_PROTOCOL = 1,
|
||||
T_COMPACT_PROTOCOL = 2,
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::protocol
|
||||
|
||||
#endif // #define _THRIFT_PROTOCOL_TPROTOCOLTYPES_H_ 1
|
513
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TVirtualProtocol.h
generated
vendored
Normal file
513
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/protocol/TVirtualProtocol.h
generated
vendored
Normal file
|
@ -0,0 +1,513 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_PROTOCOL_TVIRTUALPROTOCOL_H_
|
||||
#define _THRIFT_PROTOCOL_TVIRTUALPROTOCOL_H_ 1
|
||||
|
||||
#include <thrift/protocol/TProtocol.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace protocol {
|
||||
|
||||
using apache::thrift::transport::TTransport;
|
||||
|
||||
/**
|
||||
* Helper class that provides default implementations of TProtocol methods.
|
||||
*
|
||||
* This class provides default implementations of the non-virtual TProtocol
|
||||
* methods. It exists primarily so TVirtualProtocol can derive from it. It
|
||||
* prevents TVirtualProtocol methods from causing infinite recursion if the
|
||||
* non-virtual methods are not overridden by the TVirtualProtocol subclass.
|
||||
*
|
||||
* You probably don't want to use this class directly. Use TVirtualProtocol
|
||||
* instead.
|
||||
*/
|
||||
class TProtocolDefaults : public TProtocol {
|
||||
public:
|
||||
uint32_t readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqid) {
|
||||
(void)name;
|
||||
(void)messageType;
|
||||
(void)seqid;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support reading (yet).");
|
||||
}
|
||||
|
||||
uint32_t readMessageEnd() {
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support reading (yet).");
|
||||
}
|
||||
|
||||
uint32_t readStructBegin(std::string& name) {
|
||||
(void)name;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support reading (yet).");
|
||||
}
|
||||
|
||||
uint32_t readStructEnd() {
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support reading (yet).");
|
||||
}
|
||||
|
||||
uint32_t readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId) {
|
||||
(void)name;
|
||||
(void)fieldType;
|
||||
(void)fieldId;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support reading (yet).");
|
||||
}
|
||||
|
||||
uint32_t readFieldEnd() {
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support reading (yet).");
|
||||
}
|
||||
|
||||
uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size) {
|
||||
(void)keyType;
|
||||
(void)valType;
|
||||
(void)size;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support reading (yet).");
|
||||
}
|
||||
|
||||
uint32_t readMapEnd() {
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support reading (yet).");
|
||||
}
|
||||
|
||||
uint32_t readListBegin(TType& elemType, uint32_t& size) {
|
||||
(void)elemType;
|
||||
(void)size;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support reading (yet).");
|
||||
}
|
||||
|
||||
uint32_t readListEnd() {
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support reading (yet).");
|
||||
}
|
||||
|
||||
uint32_t readSetBegin(TType& elemType, uint32_t& size) {
|
||||
(void)elemType;
|
||||
(void)size;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support reading (yet).");
|
||||
}
|
||||
|
||||
uint32_t readSetEnd() {
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support reading (yet).");
|
||||
}
|
||||
|
||||
uint32_t readBool(bool& value) {
|
||||
(void)value;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support reading (yet).");
|
||||
}
|
||||
|
||||
uint32_t readBool(std::vector<bool>::reference value) {
|
||||
(void)value;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support reading (yet).");
|
||||
}
|
||||
|
||||
uint32_t readByte(int8_t& byte) {
|
||||
(void)byte;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support reading (yet).");
|
||||
}
|
||||
|
||||
uint32_t readI16(int16_t& i16) {
|
||||
(void)i16;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support reading (yet).");
|
||||
}
|
||||
|
||||
uint32_t readI32(int32_t& i32) {
|
||||
(void)i32;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support reading (yet).");
|
||||
}
|
||||
|
||||
uint32_t readI64(int64_t& i64) {
|
||||
(void)i64;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support reading (yet).");
|
||||
}
|
||||
|
||||
uint32_t readDouble(double& dub) {
|
||||
(void)dub;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support reading (yet).");
|
||||
}
|
||||
|
||||
uint32_t readString(std::string& str) {
|
||||
(void)str;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support reading (yet).");
|
||||
}
|
||||
|
||||
uint32_t readBinary(std::string& str) {
|
||||
(void)str;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support reading (yet).");
|
||||
}
|
||||
|
||||
uint32_t writeMessageBegin(const std::string& name,
|
||||
const TMessageType messageType,
|
||||
const int32_t seqid) {
|
||||
(void)name;
|
||||
(void)messageType;
|
||||
(void)seqid;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support writing (yet).");
|
||||
}
|
||||
|
||||
uint32_t writeMessageEnd() {
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support writing (yet).");
|
||||
}
|
||||
|
||||
uint32_t writeStructBegin(const char* name) {
|
||||
(void)name;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support writing (yet).");
|
||||
}
|
||||
|
||||
uint32_t writeStructEnd() {
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support writing (yet).");
|
||||
}
|
||||
|
||||
uint32_t writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId) {
|
||||
(void)name;
|
||||
(void)fieldType;
|
||||
(void)fieldId;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support writing (yet).");
|
||||
}
|
||||
|
||||
uint32_t writeFieldEnd() {
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support writing (yet).");
|
||||
}
|
||||
|
||||
uint32_t writeFieldStop() {
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support writing (yet).");
|
||||
}
|
||||
|
||||
uint32_t writeMapBegin(const TType keyType, const TType valType, const uint32_t size) {
|
||||
(void)keyType;
|
||||
(void)valType;
|
||||
(void)size;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support writing (yet).");
|
||||
}
|
||||
|
||||
uint32_t writeMapEnd() {
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support writing (yet).");
|
||||
}
|
||||
|
||||
uint32_t writeListBegin(const TType elemType, const uint32_t size) {
|
||||
(void)elemType;
|
||||
(void)size;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support writing (yet).");
|
||||
}
|
||||
|
||||
uint32_t writeListEnd() {
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support writing (yet).");
|
||||
}
|
||||
|
||||
uint32_t writeSetBegin(const TType elemType, const uint32_t size) {
|
||||
(void)elemType;
|
||||
(void)size;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support writing (yet).");
|
||||
}
|
||||
|
||||
uint32_t writeSetEnd() {
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support writing (yet).");
|
||||
}
|
||||
|
||||
uint32_t writeBool(const bool value) {
|
||||
(void)value;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support writing (yet).");
|
||||
}
|
||||
|
||||
uint32_t writeByte(const int8_t byte) {
|
||||
(void)byte;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support writing (yet).");
|
||||
}
|
||||
|
||||
uint32_t writeI16(const int16_t i16) {
|
||||
(void)i16;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support writing (yet).");
|
||||
}
|
||||
|
||||
uint32_t writeI32(const int32_t i32) {
|
||||
(void)i32;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support writing (yet).");
|
||||
}
|
||||
|
||||
uint32_t writeI64(const int64_t i64) {
|
||||
(void)i64;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support writing (yet).");
|
||||
}
|
||||
|
||||
uint32_t writeDouble(const double dub) {
|
||||
(void)dub;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support writing (yet).");
|
||||
}
|
||||
|
||||
uint32_t writeString(const std::string& str) {
|
||||
(void)str;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support writing (yet).");
|
||||
}
|
||||
|
||||
uint32_t writeBinary(const std::string& str) {
|
||||
(void)str;
|
||||
throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
|
||||
"this protocol does not support writing (yet).");
|
||||
}
|
||||
|
||||
uint32_t skip(TType type) { return ::apache::thrift::protocol::skip(*this, type); }
|
||||
|
||||
protected:
|
||||
TProtocolDefaults(boost::shared_ptr<TTransport> ptrans) : TProtocol(ptrans) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Concrete TProtocol classes should inherit from TVirtualProtocol
|
||||
* so they don't have to manually override virtual methods.
|
||||
*/
|
||||
template <class Protocol_, class Super_ = TProtocolDefaults>
|
||||
class TVirtualProtocol : public Super_ {
|
||||
public:
|
||||
/**
|
||||
* Writing functions.
|
||||
*/
|
||||
|
||||
virtual uint32_t writeMessageBegin_virt(const std::string& name,
|
||||
const TMessageType messageType,
|
||||
const int32_t seqid) {
|
||||
return static_cast<Protocol_*>(this)->writeMessageBegin(name, messageType, seqid);
|
||||
}
|
||||
|
||||
virtual uint32_t writeMessageEnd_virt() {
|
||||
return static_cast<Protocol_*>(this)->writeMessageEnd();
|
||||
}
|
||||
|
||||
virtual uint32_t writeStructBegin_virt(const char* name) {
|
||||
return static_cast<Protocol_*>(this)->writeStructBegin(name);
|
||||
}
|
||||
|
||||
virtual uint32_t writeStructEnd_virt() { return static_cast<Protocol_*>(this)->writeStructEnd(); }
|
||||
|
||||
virtual uint32_t writeFieldBegin_virt(const char* name,
|
||||
const TType fieldType,
|
||||
const int16_t fieldId) {
|
||||
return static_cast<Protocol_*>(this)->writeFieldBegin(name, fieldType, fieldId);
|
||||
}
|
||||
|
||||
virtual uint32_t writeFieldEnd_virt() { return static_cast<Protocol_*>(this)->writeFieldEnd(); }
|
||||
|
||||
virtual uint32_t writeFieldStop_virt() { return static_cast<Protocol_*>(this)->writeFieldStop(); }
|
||||
|
||||
virtual uint32_t writeMapBegin_virt(const TType keyType,
|
||||
const TType valType,
|
||||
const uint32_t size) {
|
||||
return static_cast<Protocol_*>(this)->writeMapBegin(keyType, valType, size);
|
||||
}
|
||||
|
||||
virtual uint32_t writeMapEnd_virt() { return static_cast<Protocol_*>(this)->writeMapEnd(); }
|
||||
|
||||
virtual uint32_t writeListBegin_virt(const TType elemType, const uint32_t size) {
|
||||
return static_cast<Protocol_*>(this)->writeListBegin(elemType, size);
|
||||
}
|
||||
|
||||
virtual uint32_t writeListEnd_virt() { return static_cast<Protocol_*>(this)->writeListEnd(); }
|
||||
|
||||
virtual uint32_t writeSetBegin_virt(const TType elemType, const uint32_t size) {
|
||||
return static_cast<Protocol_*>(this)->writeSetBegin(elemType, size);
|
||||
}
|
||||
|
||||
virtual uint32_t writeSetEnd_virt() { return static_cast<Protocol_*>(this)->writeSetEnd(); }
|
||||
|
||||
virtual uint32_t writeBool_virt(const bool value) {
|
||||
return static_cast<Protocol_*>(this)->writeBool(value);
|
||||
}
|
||||
|
||||
virtual uint32_t writeByte_virt(const int8_t byte) {
|
||||
return static_cast<Protocol_*>(this)->writeByte(byte);
|
||||
}
|
||||
|
||||
virtual uint32_t writeI16_virt(const int16_t i16) {
|
||||
return static_cast<Protocol_*>(this)->writeI16(i16);
|
||||
}
|
||||
|
||||
virtual uint32_t writeI32_virt(const int32_t i32) {
|
||||
return static_cast<Protocol_*>(this)->writeI32(i32);
|
||||
}
|
||||
|
||||
virtual uint32_t writeI64_virt(const int64_t i64) {
|
||||
return static_cast<Protocol_*>(this)->writeI64(i64);
|
||||
}
|
||||
|
||||
virtual uint32_t writeDouble_virt(const double dub) {
|
||||
return static_cast<Protocol_*>(this)->writeDouble(dub);
|
||||
}
|
||||
|
||||
virtual uint32_t writeString_virt(const std::string& str) {
|
||||
return static_cast<Protocol_*>(this)->writeString(str);
|
||||
}
|
||||
|
||||
virtual uint32_t writeBinary_virt(const std::string& str) {
|
||||
return static_cast<Protocol_*>(this)->writeBinary(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reading functions
|
||||
*/
|
||||
|
||||
virtual uint32_t readMessageBegin_virt(std::string& name,
|
||||
TMessageType& messageType,
|
||||
int32_t& seqid) {
|
||||
return static_cast<Protocol_*>(this)->readMessageBegin(name, messageType, seqid);
|
||||
}
|
||||
|
||||
virtual uint32_t readMessageEnd_virt() { return static_cast<Protocol_*>(this)->readMessageEnd(); }
|
||||
|
||||
virtual uint32_t readStructBegin_virt(std::string& name) {
|
||||
return static_cast<Protocol_*>(this)->readStructBegin(name);
|
||||
}
|
||||
|
||||
virtual uint32_t readStructEnd_virt() { return static_cast<Protocol_*>(this)->readStructEnd(); }
|
||||
|
||||
virtual uint32_t readFieldBegin_virt(std::string& name, TType& fieldType, int16_t& fieldId) {
|
||||
return static_cast<Protocol_*>(this)->readFieldBegin(name, fieldType, fieldId);
|
||||
}
|
||||
|
||||
virtual uint32_t readFieldEnd_virt() { return static_cast<Protocol_*>(this)->readFieldEnd(); }
|
||||
|
||||
virtual uint32_t readMapBegin_virt(TType& keyType, TType& valType, uint32_t& size) {
|
||||
return static_cast<Protocol_*>(this)->readMapBegin(keyType, valType, size);
|
||||
}
|
||||
|
||||
virtual uint32_t readMapEnd_virt() { return static_cast<Protocol_*>(this)->readMapEnd(); }
|
||||
|
||||
virtual uint32_t readListBegin_virt(TType& elemType, uint32_t& size) {
|
||||
return static_cast<Protocol_*>(this)->readListBegin(elemType, size);
|
||||
}
|
||||
|
||||
virtual uint32_t readListEnd_virt() { return static_cast<Protocol_*>(this)->readListEnd(); }
|
||||
|
||||
virtual uint32_t readSetBegin_virt(TType& elemType, uint32_t& size) {
|
||||
return static_cast<Protocol_*>(this)->readSetBegin(elemType, size);
|
||||
}
|
||||
|
||||
virtual uint32_t readSetEnd_virt() { return static_cast<Protocol_*>(this)->readSetEnd(); }
|
||||
|
||||
virtual uint32_t readBool_virt(bool& value) {
|
||||
return static_cast<Protocol_*>(this)->readBool(value);
|
||||
}
|
||||
|
||||
virtual uint32_t readBool_virt(std::vector<bool>::reference value) {
|
||||
return static_cast<Protocol_*>(this)->readBool(value);
|
||||
}
|
||||
|
||||
virtual uint32_t readByte_virt(int8_t& byte) {
|
||||
return static_cast<Protocol_*>(this)->readByte(byte);
|
||||
}
|
||||
|
||||
virtual uint32_t readI16_virt(int16_t& i16) {
|
||||
return static_cast<Protocol_*>(this)->readI16(i16);
|
||||
}
|
||||
|
||||
virtual uint32_t readI32_virt(int32_t& i32) {
|
||||
return static_cast<Protocol_*>(this)->readI32(i32);
|
||||
}
|
||||
|
||||
virtual uint32_t readI64_virt(int64_t& i64) {
|
||||
return static_cast<Protocol_*>(this)->readI64(i64);
|
||||
}
|
||||
|
||||
virtual uint32_t readDouble_virt(double& dub) {
|
||||
return static_cast<Protocol_*>(this)->readDouble(dub);
|
||||
}
|
||||
|
||||
virtual uint32_t readString_virt(std::string& str) {
|
||||
return static_cast<Protocol_*>(this)->readString(str);
|
||||
}
|
||||
|
||||
virtual uint32_t readBinary_virt(std::string& str) {
|
||||
return static_cast<Protocol_*>(this)->readBinary(str);
|
||||
}
|
||||
|
||||
virtual uint32_t skip_virt(TType type) { return static_cast<Protocol_*>(this)->skip(type); }
|
||||
|
||||
/*
|
||||
* Provide a default skip() implementation that uses non-virtual read
|
||||
* methods.
|
||||
*
|
||||
* Note: subclasses that use TVirtualProtocol to derive from another protocol
|
||||
* implementation (i.e., not TProtocolDefaults) should beware that this may
|
||||
* override any non-default skip() implementation provided by the parent
|
||||
* transport class. They may need to explicitly redefine skip() to call the
|
||||
* correct parent implementation, if desired.
|
||||
*/
|
||||
uint32_t skip(TType type) {
|
||||
Protocol_* const prot = static_cast<Protocol_*>(this);
|
||||
return ::apache::thrift::protocol::skip(*prot, type);
|
||||
}
|
||||
|
||||
/*
|
||||
* Provide a default readBool() implementation for use with
|
||||
* std::vector<bool>, that behaves the same as reading into a normal bool.
|
||||
*
|
||||
* Subclasses can override this if desired, but there normally shouldn't
|
||||
* be a need to.
|
||||
*/
|
||||
uint32_t readBool(std::vector<bool>::reference value) {
|
||||
bool b = false;
|
||||
uint32_t ret = static_cast<Protocol_*>(this)->readBool(b);
|
||||
value = b;
|
||||
return ret;
|
||||
}
|
||||
using Super_::readBool; // so we don't hide readBool(bool&)
|
||||
|
||||
protected:
|
||||
TVirtualProtocol(boost::shared_ptr<TTransport> ptrans) : Super_(ptrans) {}
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::protocol
|
||||
|
||||
#endif // #define _THRIFT_PROTOCOL_TVIRTUALPROTOCOL_H_ 1
|
28
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/qt/CMakeLists.txt
generated
vendored
Normal file
28
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/qt/CMakeLists.txt
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
set( thriftcppqt5_SOURCES
|
||||
TQIODeviceTransport.cpp
|
||||
TQTcpServer.cpp
|
||||
)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
find_package(Qt5 REQUIRED COMPONENTS Core Network)
|
||||
ADD_LIBRARY_THRIFT(thriftqt5 ${thriftcppqt5_SOURCES})
|
||||
TARGET_LINK_LIBRARIES_THRIFT(thriftqt5 Qt5::Core Qt5::Network)
|
||||
TARGET_LINK_LIBRARIES_THRIFT_AGAINST_THRIFT_LIBRARY(thriftqt5 thrift)
|
167
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/qt/TQIODeviceTransport.cpp
generated
vendored
Normal file
167
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/qt/TQIODeviceTransport.cpp
generated
vendored
Normal file
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/qt/TQIODeviceTransport.h>
|
||||
|
||||
#include <QAbstractSocket>
|
||||
#include <QIODevice>
|
||||
|
||||
#include <thrift/transport/TBufferTransports.h>
|
||||
|
||||
using boost::shared_ptr;
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace transport {
|
||||
|
||||
TQIODeviceTransport::TQIODeviceTransport(shared_ptr<QIODevice> dev) : dev_(dev) {
|
||||
}
|
||||
|
||||
TQIODeviceTransport::~TQIODeviceTransport() {
|
||||
dev_->close();
|
||||
}
|
||||
|
||||
void TQIODeviceTransport::open() {
|
||||
if (!isOpen()) {
|
||||
throw TTransportException(TTransportException::NOT_OPEN,
|
||||
"open(): underlying QIODevice isn't open");
|
||||
}
|
||||
}
|
||||
|
||||
bool TQIODeviceTransport::isOpen() {
|
||||
return dev_->isOpen();
|
||||
}
|
||||
|
||||
bool TQIODeviceTransport::peek() {
|
||||
return dev_->bytesAvailable() > 0;
|
||||
}
|
||||
|
||||
void TQIODeviceTransport::close() {
|
||||
dev_->close();
|
||||
}
|
||||
|
||||
uint32_t TQIODeviceTransport::readAll(uint8_t* buf, uint32_t len) {
|
||||
uint32_t requestLen = len;
|
||||
while (len) {
|
||||
uint32_t readSize;
|
||||
try {
|
||||
readSize = read(buf, len);
|
||||
} catch (...) {
|
||||
if (len != requestLen) {
|
||||
// something read already
|
||||
return requestLen - len;
|
||||
}
|
||||
// error but nothing read yet
|
||||
throw;
|
||||
}
|
||||
if (readSize == 0) {
|
||||
dev_->waitForReadyRead(50);
|
||||
} else {
|
||||
buf += readSize;
|
||||
len -= readSize;
|
||||
}
|
||||
}
|
||||
return requestLen;
|
||||
}
|
||||
|
||||
uint32_t TQIODeviceTransport::read(uint8_t* buf, uint32_t len) {
|
||||
uint32_t actualSize;
|
||||
qint64 readSize;
|
||||
|
||||
if (!dev_->isOpen()) {
|
||||
throw TTransportException(TTransportException::NOT_OPEN,
|
||||
"read(): underlying QIODevice is not open");
|
||||
}
|
||||
|
||||
actualSize = (uint32_t)std::min((qint64)len, dev_->bytesAvailable());
|
||||
readSize = dev_->read(reinterpret_cast<char*>(buf), actualSize);
|
||||
|
||||
if (readSize < 0) {
|
||||
QAbstractSocket* socket;
|
||||
if ((socket = qobject_cast<QAbstractSocket*>(dev_.get()))) {
|
||||
throw TTransportException(TTransportException::UNKNOWN,
|
||||
"Failed to read() from QAbstractSocket",
|
||||
socket->error());
|
||||
}
|
||||
throw TTransportException(TTransportException::UNKNOWN, "Failed to read from from QIODevice");
|
||||
}
|
||||
|
||||
return (uint32_t)readSize;
|
||||
}
|
||||
|
||||
void TQIODeviceTransport::write(const uint8_t* buf, uint32_t len) {
|
||||
while (len) {
|
||||
uint32_t written = write_partial(buf, len);
|
||||
len -= written;
|
||||
dev_->waitForBytesWritten(50);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t TQIODeviceTransport::write_partial(const uint8_t* buf, uint32_t len) {
|
||||
qint64 written;
|
||||
|
||||
if (!dev_->isOpen()) {
|
||||
throw TTransportException(TTransportException::NOT_OPEN,
|
||||
"write_partial(): underlying QIODevice is not open");
|
||||
}
|
||||
|
||||
written = dev_->write(reinterpret_cast<const char*>(buf), len);
|
||||
if (written < 0) {
|
||||
QAbstractSocket* socket;
|
||||
if ((socket = qobject_cast<QAbstractSocket*>(dev_.get()))) {
|
||||
throw TTransportException(TTransportException::UNKNOWN,
|
||||
"write_partial(): failed to write to QAbstractSocket",
|
||||
socket->error());
|
||||
}
|
||||
|
||||
throw TTransportException(TTransportException::UNKNOWN,
|
||||
"write_partial(): failed to write to underlying QIODevice");
|
||||
}
|
||||
|
||||
return (uint32_t)written;
|
||||
}
|
||||
|
||||
void TQIODeviceTransport::flush() {
|
||||
if (!dev_->isOpen()) {
|
||||
throw TTransportException(TTransportException::NOT_OPEN,
|
||||
"flush(): underlying QIODevice is not open");
|
||||
}
|
||||
|
||||
QAbstractSocket* socket;
|
||||
|
||||
if ((socket = qobject_cast<QAbstractSocket*>(dev_.get()))) {
|
||||
socket->flush();
|
||||
} else {
|
||||
dev_->waitForBytesWritten(1);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* TQIODeviceTransport::borrow(uint8_t* buf, uint32_t* len) {
|
||||
(void)buf;
|
||||
(void)len;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void TQIODeviceTransport::consume(uint32_t len) {
|
||||
(void)len;
|
||||
throw TTransportException(TTransportException::UNKNOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::transport
|
68
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/qt/TQIODeviceTransport.h
generated
vendored
Normal file
68
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/qt/TQIODeviceTransport.h
generated
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_ASYNC_TQIODEVICE_TRANSPORT_H_
|
||||
#define _THRIFT_ASYNC_TQIODEVICE_TRANSPORT_H_ 1
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <thrift/transport/TVirtualTransport.h>
|
||||
|
||||
class QIODevice;
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace transport {
|
||||
|
||||
/**
|
||||
* Transport that operates on a QIODevice (socket, file, etc).
|
||||
*/
|
||||
class TQIODeviceTransport
|
||||
: public apache::thrift::transport::TVirtualTransport<TQIODeviceTransport> {
|
||||
public:
|
||||
explicit TQIODeviceTransport(boost::shared_ptr<QIODevice> dev);
|
||||
virtual ~TQIODeviceTransport();
|
||||
|
||||
void open();
|
||||
bool isOpen();
|
||||
bool peek();
|
||||
void close();
|
||||
|
||||
uint32_t readAll(uint8_t* buf, uint32_t len);
|
||||
uint32_t read(uint8_t* buf, uint32_t len);
|
||||
|
||||
void write(const uint8_t* buf, uint32_t len);
|
||||
uint32_t write_partial(const uint8_t* buf, uint32_t len);
|
||||
|
||||
void flush();
|
||||
|
||||
uint8_t* borrow(uint8_t* buf, uint32_t* len);
|
||||
void consume(uint32_t len);
|
||||
|
||||
private:
|
||||
TQIODeviceTransport(const TQIODeviceTransport&);
|
||||
TQIODeviceTransport& operator=(const TQIODeviceTransport&);
|
||||
|
||||
boost::shared_ptr<QIODevice> dev_;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::transport
|
||||
|
||||
#endif // #ifndef _THRIFT_ASYNC_TQIODEVICE_TRANSPORT_H_
|
150
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/qt/TQTcpServer.cpp
generated
vendored
Normal file
150
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/qt/TQTcpServer.cpp
generated
vendored
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/qt/TQTcpServer.h>
|
||||
#include <thrift/qt/TQIODeviceTransport.h>
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QTcpSocket>
|
||||
|
||||
#include <thrift/cxxfunctional.h>
|
||||
|
||||
#include <thrift/protocol/TProtocol.h>
|
||||
#include <thrift/async/TAsyncProcessor.h>
|
||||
|
||||
using boost::shared_ptr;
|
||||
using apache::thrift::protocol::TProtocol;
|
||||
using apache::thrift::protocol::TProtocolFactory;
|
||||
using apache::thrift::transport::TTransport;
|
||||
using apache::thrift::transport::TTransportException;
|
||||
using apache::thrift::transport::TQIODeviceTransport;
|
||||
using apache::thrift::stdcxx::function;
|
||||
using apache::thrift::stdcxx::bind;
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace async {
|
||||
|
||||
struct TQTcpServer::ConnectionContext {
|
||||
shared_ptr<QTcpSocket> connection_;
|
||||
shared_ptr<TTransport> transport_;
|
||||
shared_ptr<TProtocol> iprot_;
|
||||
shared_ptr<TProtocol> oprot_;
|
||||
|
||||
explicit ConnectionContext(shared_ptr<QTcpSocket> connection,
|
||||
shared_ptr<TTransport> transport,
|
||||
shared_ptr<TProtocol> iprot,
|
||||
shared_ptr<TProtocol> oprot)
|
||||
: connection_(connection), transport_(transport), iprot_(iprot), oprot_(oprot) {}
|
||||
};
|
||||
|
||||
TQTcpServer::TQTcpServer(shared_ptr<QTcpServer> server,
|
||||
shared_ptr<TAsyncProcessor> processor,
|
||||
shared_ptr<TProtocolFactory> pfact,
|
||||
QObject* parent)
|
||||
: QObject(parent), server_(server), processor_(processor), pfact_(pfact) {
|
||||
qRegisterMetaType<QTcpSocket*>("QTcpSocket*");
|
||||
connect(server.get(), SIGNAL(newConnection()), SLOT(processIncoming()));
|
||||
}
|
||||
|
||||
TQTcpServer::~TQTcpServer() {
|
||||
}
|
||||
|
||||
void TQTcpServer::processIncoming() {
|
||||
while (server_->hasPendingConnections()) {
|
||||
// take ownership of the QTcpSocket; technically it could be deleted
|
||||
// when the QTcpServer is destroyed, but any real app should delete this
|
||||
// class before deleting the QTcpServer that we are using
|
||||
shared_ptr<QTcpSocket> connection(server_->nextPendingConnection());
|
||||
|
||||
shared_ptr<TTransport> transport;
|
||||
shared_ptr<TProtocol> iprot;
|
||||
shared_ptr<TProtocol> oprot;
|
||||
|
||||
try {
|
||||
transport = shared_ptr<TTransport>(new TQIODeviceTransport(connection));
|
||||
iprot = shared_ptr<TProtocol>(pfact_->getProtocol(transport));
|
||||
oprot = shared_ptr<TProtocol>(pfact_->getProtocol(transport));
|
||||
} catch (...) {
|
||||
qWarning("[TQTcpServer] Failed to initialize transports/protocols");
|
||||
continue;
|
||||
}
|
||||
|
||||
ctxMap_[connection.get()]
|
||||
= shared_ptr<ConnectionContext>(new ConnectionContext(connection, transport, iprot, oprot));
|
||||
|
||||
connect(connection.get(), SIGNAL(readyRead()), SLOT(beginDecode()));
|
||||
|
||||
connect(connection.get(), SIGNAL(disconnected()), SLOT(socketClosed()));
|
||||
}
|
||||
}
|
||||
|
||||
void TQTcpServer::beginDecode() {
|
||||
QTcpSocket* connection(qobject_cast<QTcpSocket*>(sender()));
|
||||
Q_ASSERT(connection);
|
||||
|
||||
if (ctxMap_.find(connection) == ctxMap_.end()) {
|
||||
qWarning("[TQTcpServer] Got data on an unknown QTcpSocket");
|
||||
return;
|
||||
}
|
||||
|
||||
shared_ptr<ConnectionContext> ctx = ctxMap_[connection];
|
||||
|
||||
try {
|
||||
processor_
|
||||
->process(bind(&TQTcpServer::finish, this, ctx, apache::thrift::stdcxx::placeholders::_1),
|
||||
ctx->iprot_,
|
||||
ctx->oprot_);
|
||||
} catch (const TTransportException& ex) {
|
||||
qWarning("[TQTcpServer] TTransportException during processing: '%s'", ex.what());
|
||||
scheduleDeleteConnectionContext(connection);
|
||||
} catch (...) {
|
||||
qWarning("[TQTcpServer] Unknown processor exception");
|
||||
scheduleDeleteConnectionContext(connection);
|
||||
}
|
||||
}
|
||||
|
||||
void TQTcpServer::socketClosed() {
|
||||
QTcpSocket* connection(qobject_cast<QTcpSocket*>(sender()));
|
||||
Q_ASSERT(connection);
|
||||
scheduleDeleteConnectionContext(connection);
|
||||
}
|
||||
|
||||
void TQTcpServer::deleteConnectionContext(QTcpSocket* connection) {
|
||||
const ConnectionContextMap::size_type deleted = ctxMap_.erase(connection);
|
||||
if (0 == deleted) {
|
||||
qWarning("[TQTcpServer] Unknown QTcpSocket");
|
||||
}
|
||||
}
|
||||
|
||||
void TQTcpServer::scheduleDeleteConnectionContext(QTcpSocket* connection) {
|
||||
QMetaObject::invokeMethod(this, "deleteConnectionContext", Qt::QueuedConnection, Q_ARG(QTcpSocket*, connection));
|
||||
}
|
||||
|
||||
void TQTcpServer::finish(shared_ptr<ConnectionContext> ctx, bool healthy) {
|
||||
if (!healthy) {
|
||||
qWarning("[TQTcpServer] Processor failed to process data successfully");
|
||||
deleteConnectionContext(ctx->connection_.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::async
|
81
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/qt/TQTcpServer.h
generated
vendored
Normal file
81
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/qt/TQTcpServer.h
generated
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_TASYNC_QTCP_SERVER_H_
|
||||
#define _THRIFT_TASYNC_QTCP_SERVER_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <QTcpServer>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace protocol {
|
||||
class TProtocolFactory;
|
||||
}
|
||||
}
|
||||
} // apache::thrift::protocol
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace async {
|
||||
|
||||
class TAsyncProcessor;
|
||||
|
||||
/**
|
||||
* Server that uses Qt to listen for connections.
|
||||
* Simply give it a QTcpServer that is listening, along with an async
|
||||
* processor and a protocol factory, and then run the Qt event loop.
|
||||
*/
|
||||
class TQTcpServer : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
TQTcpServer(boost::shared_ptr<QTcpServer> server,
|
||||
boost::shared_ptr<TAsyncProcessor> processor,
|
||||
boost::shared_ptr<apache::thrift::protocol::TProtocolFactory> protocolFactory,
|
||||
QObject* parent = NULL);
|
||||
virtual ~TQTcpServer();
|
||||
|
||||
private Q_SLOTS:
|
||||
void processIncoming();
|
||||
void beginDecode();
|
||||
void socketClosed();
|
||||
void deleteConnectionContext(QTcpSocket* connection);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(TQTcpServer)
|
||||
|
||||
struct ConnectionContext;
|
||||
|
||||
void scheduleDeleteConnectionContext(QTcpSocket* connection);
|
||||
void finish(boost::shared_ptr<ConnectionContext> ctx, bool healthy);
|
||||
|
||||
boost::shared_ptr<QTcpServer> server_;
|
||||
boost::shared_ptr<TAsyncProcessor> processor_;
|
||||
boost::shared_ptr<apache::thrift::protocol::TProtocolFactory> pfact_;
|
||||
|
||||
typedef std::map<QTcpSocket*, boost::shared_ptr<ConnectionContext> > ConnectionContextMap;
|
||||
ConnectionContextMap ctxMap_;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::async
|
||||
|
||||
#endif // #ifndef _THRIFT_TASYNC_QTCP_SERVER_H_
|
123
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TConnectedClient.cpp
generated
vendored
Normal file
123
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TConnectedClient.cpp
generated
vendored
Normal file
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/server/TConnectedClient.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace server {
|
||||
|
||||
using apache::thrift::TProcessor;
|
||||
using apache::thrift::protocol::TProtocol;
|
||||
using apache::thrift::server::TServerEventHandler;
|
||||
using apache::thrift::transport::TTransport;
|
||||
using apache::thrift::transport::TTransportException;
|
||||
using boost::shared_ptr;
|
||||
using std::string;
|
||||
|
||||
TConnectedClient::TConnectedClient(const shared_ptr<TProcessor>& processor,
|
||||
const shared_ptr<TProtocol>& inputProtocol,
|
||||
const shared_ptr<TProtocol>& outputProtocol,
|
||||
const shared_ptr<TServerEventHandler>& eventHandler,
|
||||
const shared_ptr<TTransport>& client)
|
||||
|
||||
: processor_(processor),
|
||||
inputProtocol_(inputProtocol),
|
||||
outputProtocol_(outputProtocol),
|
||||
eventHandler_(eventHandler),
|
||||
client_(client),
|
||||
opaqueContext_(0) {
|
||||
}
|
||||
|
||||
TConnectedClient::~TConnectedClient() {
|
||||
}
|
||||
|
||||
void TConnectedClient::run() {
|
||||
if (eventHandler_) {
|
||||
opaqueContext_ = eventHandler_->createContext(inputProtocol_, outputProtocol_);
|
||||
}
|
||||
|
||||
for (bool done = false; !done;) {
|
||||
if (eventHandler_) {
|
||||
eventHandler_->processContext(opaqueContext_, client_);
|
||||
}
|
||||
|
||||
try {
|
||||
if (!processor_->process(inputProtocol_, outputProtocol_, opaqueContext_)) {
|
||||
break;
|
||||
}
|
||||
} catch (const TTransportException& ttx) {
|
||||
switch (ttx.getType()) {
|
||||
case TTransportException::END_OF_FILE:
|
||||
case TTransportException::INTERRUPTED:
|
||||
case TTransportException::TIMED_OUT:
|
||||
// Client disconnected or was interrupted or did not respond within the receive timeout.
|
||||
// No logging needed. Done.
|
||||
done = true;
|
||||
break;
|
||||
|
||||
default: {
|
||||
// All other transport exceptions are logged.
|
||||
// State of connection is unknown. Done.
|
||||
string errStr = string("TConnectedClient died: ") + ttx.what();
|
||||
GlobalOutput(errStr.c_str());
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (const TException& tex) {
|
||||
string errStr = string("TConnectedClient processing exception: ") + tex.what();
|
||||
GlobalOutput(errStr.c_str());
|
||||
// Disconnect from client, because we could not process the message.
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup();
|
||||
}
|
||||
|
||||
void TConnectedClient::cleanup() {
|
||||
if (eventHandler_) {
|
||||
eventHandler_->deleteContext(opaqueContext_, inputProtocol_, outputProtocol_);
|
||||
}
|
||||
|
||||
try {
|
||||
inputProtocol_->getTransport()->close();
|
||||
} catch (const TTransportException& ttx) {
|
||||
string errStr = string("TConnectedClient input close failed: ") + ttx.what();
|
||||
GlobalOutput(errStr.c_str());
|
||||
}
|
||||
|
||||
try {
|
||||
outputProtocol_->getTransport()->close();
|
||||
} catch (const TTransportException& ttx) {
|
||||
string errStr = string("TConnectedClient output close failed: ") + ttx.what();
|
||||
GlobalOutput(errStr.c_str());
|
||||
}
|
||||
|
||||
try {
|
||||
client_->close();
|
||||
} catch (const TTransportException& ttx) {
|
||||
string errStr = string("TConnectedClient client close failed: ") + ttx.what();
|
||||
GlobalOutput(errStr.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::server
|
110
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TConnectedClient.h
generated
vendored
Normal file
110
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TConnectedClient.h
generated
vendored
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_SERVER_TCONNECTEDCLIENT_H_
|
||||
#define _THRIFT_SERVER_TCONNECTEDCLIENT_H_ 1
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <thrift/TProcessor.h>
|
||||
#include <thrift/protocol/TProtocol.h>
|
||||
#include <thrift/server/TServer.h>
|
||||
#include <thrift/transport/TTransport.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace server {
|
||||
|
||||
/**
|
||||
* This represents a client connected to a TServer. The
|
||||
* processing loop for a client must provide some required
|
||||
* functionality common to all implementations so it is
|
||||
* encapsulated here.
|
||||
*/
|
||||
|
||||
class TConnectedClient : public apache::thrift::concurrency::Runnable {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param[in] processor the TProcessor
|
||||
* @param[in] inputProtocol the input TProtocol
|
||||
* @param[in] outputProtocol the output TProtocol
|
||||
* @param[in] eventHandler the server event handler
|
||||
* @param[in] client the TTransport representing the client
|
||||
*/
|
||||
TConnectedClient(
|
||||
const boost::shared_ptr<apache::thrift::TProcessor>& processor,
|
||||
const boost::shared_ptr<apache::thrift::protocol::TProtocol>& inputProtocol,
|
||||
const boost::shared_ptr<apache::thrift::protocol::TProtocol>& outputProtocol,
|
||||
const boost::shared_ptr<apache::thrift::server::TServerEventHandler>& eventHandler,
|
||||
const boost::shared_ptr<apache::thrift::transport::TTransport>& client);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~TConnectedClient();
|
||||
|
||||
/**
|
||||
* Drive the client until it is done.
|
||||
* The client processing loop is:
|
||||
*
|
||||
* [optional] call eventHandler->createContext once
|
||||
* [optional] call eventHandler->processContext per request
|
||||
* call processor->process per request
|
||||
* handle expected transport exceptions:
|
||||
* END_OF_FILE means the client is gone
|
||||
* INTERRUPTED means the client was interrupted
|
||||
* by TServerTransport::interruptChildren()
|
||||
* handle unexpected transport exceptions by logging
|
||||
* handle standard exceptions by logging
|
||||
* handle unexpected exceptions by logging
|
||||
* cleanup()
|
||||
*/
|
||||
virtual void run() /* override */;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Cleanup after a client. This happens if the client disconnects,
|
||||
* or if the server is stopped, or if an exception occurs.
|
||||
*
|
||||
* The cleanup processing is:
|
||||
* [optional] call eventHandler->deleteContext once
|
||||
* close the inputProtocol's TTransport
|
||||
* close the outputProtocol's TTransport
|
||||
* close the client
|
||||
*/
|
||||
virtual void cleanup();
|
||||
|
||||
private:
|
||||
boost::shared_ptr<apache::thrift::TProcessor> processor_;
|
||||
boost::shared_ptr<apache::thrift::protocol::TProtocol> inputProtocol_;
|
||||
boost::shared_ptr<apache::thrift::protocol::TProtocol> outputProtocol_;
|
||||
boost::shared_ptr<apache::thrift::server::TServerEventHandler> eventHandler_;
|
||||
boost::shared_ptr<apache::thrift::transport::TTransport> client_;
|
||||
|
||||
/**
|
||||
* Context acquired from the eventHandler_ if one exists.
|
||||
*/
|
||||
void* opaqueContext_;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #ifndef _THRIFT_SERVER_TCONNECTEDCLIENT_H_
|
1625
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TNonblockingServer.cpp
generated
vendored
Normal file
1625
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TNonblockingServer.cpp
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
877
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TNonblockingServer.h
generated
vendored
Normal file
877
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TNonblockingServer.h
generated
vendored
Normal file
|
@ -0,0 +1,877 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_SERVER_TNONBLOCKINGSERVER_H_
|
||||
#define _THRIFT_SERVER_TNONBLOCKINGSERVER_H_ 1
|
||||
|
||||
#include <thrift/Thrift.h>
|
||||
#include <thrift/server/TServer.h>
|
||||
#include <thrift/transport/PlatformSocket.h>
|
||||
#include <thrift/transport/TBufferTransports.h>
|
||||
#include <thrift/transport/TSocket.h>
|
||||
#include <thrift/concurrency/ThreadManager.h>
|
||||
#include <climits>
|
||||
#include <thrift/concurrency/Thread.h>
|
||||
#include <thrift/concurrency/PlatformThreadFactory.h>
|
||||
#include <thrift/concurrency/Mutex.h>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <event.h>
|
||||
#include <event2/event_compat.h>
|
||||
#include <event2/event_struct.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace server {
|
||||
|
||||
using apache::thrift::transport::TMemoryBuffer;
|
||||
using apache::thrift::transport::TSocket;
|
||||
using apache::thrift::protocol::TProtocol;
|
||||
using apache::thrift::concurrency::Runnable;
|
||||
using apache::thrift::concurrency::ThreadManager;
|
||||
using apache::thrift::concurrency::PlatformThreadFactory;
|
||||
using apache::thrift::concurrency::ThreadFactory;
|
||||
using apache::thrift::concurrency::Thread;
|
||||
using apache::thrift::concurrency::Mutex;
|
||||
using apache::thrift::concurrency::Guard;
|
||||
|
||||
#ifdef LIBEVENT_VERSION_NUMBER
|
||||
#define LIBEVENT_VERSION_MAJOR (LIBEVENT_VERSION_NUMBER >> 24)
|
||||
#define LIBEVENT_VERSION_MINOR ((LIBEVENT_VERSION_NUMBER >> 16) & 0xFF)
|
||||
#define LIBEVENT_VERSION_REL ((LIBEVENT_VERSION_NUMBER >> 8) & 0xFF)
|
||||
#else
|
||||
// assume latest version 1 series
|
||||
#define LIBEVENT_VERSION_MAJOR 1
|
||||
#define LIBEVENT_VERSION_MINOR 14
|
||||
#define LIBEVENT_VERSION_REL 13
|
||||
#define LIBEVENT_VERSION_NUMBER \
|
||||
((LIBEVENT_VERSION_MAJOR << 24) | (LIBEVENT_VERSION_MINOR << 16) | (LIBEVENT_VERSION_REL << 8))
|
||||
#endif
|
||||
|
||||
#if LIBEVENT_VERSION_NUMBER < 0x02000000
|
||||
typedef THRIFT_SOCKET evutil_socket_t;
|
||||
#endif
|
||||
|
||||
#ifndef SOCKOPT_CAST_T
|
||||
#ifndef _WIN32
|
||||
#define SOCKOPT_CAST_T void
|
||||
#else
|
||||
#define SOCKOPT_CAST_T char
|
||||
#endif // _WIN32
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
inline const SOCKOPT_CAST_T* const_cast_sockopt(const T* v) {
|
||||
return reinterpret_cast<const SOCKOPT_CAST_T*>(v);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline SOCKOPT_CAST_T* cast_sockopt(T* v) {
|
||||
return reinterpret_cast<SOCKOPT_CAST_T*>(v);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a non-blocking server in C++ for high performance that
|
||||
* operates a set of IO threads (by default only one). It assumes that
|
||||
* all incoming requests are framed with a 4 byte length indicator and
|
||||
* writes out responses using the same framing.
|
||||
*
|
||||
* It does not use the TServerTransport framework, but rather has socket
|
||||
* operations hardcoded for use with select.
|
||||
*
|
||||
*/
|
||||
|
||||
/// Overload condition actions.
|
||||
enum TOverloadAction {
|
||||
T_OVERLOAD_NO_ACTION, ///< Don't handle overload */
|
||||
T_OVERLOAD_CLOSE_ON_ACCEPT, ///< Drop new connections immediately */
|
||||
T_OVERLOAD_DRAIN_TASK_QUEUE ///< Drop some tasks from head of task queue */
|
||||
};
|
||||
|
||||
class TNonblockingIOThread;
|
||||
|
||||
class TNonblockingServer : public TServer {
|
||||
private:
|
||||
class TConnection;
|
||||
|
||||
friend class TNonblockingIOThread;
|
||||
|
||||
private:
|
||||
/// Listen backlog
|
||||
static const int LISTEN_BACKLOG = 1024;
|
||||
|
||||
/// Default limit on size of idle connection pool
|
||||
static const size_t CONNECTION_STACK_LIMIT = 1024;
|
||||
|
||||
/// Default limit on frame size
|
||||
static const int MAX_FRAME_SIZE = 256 * 1024 * 1024;
|
||||
|
||||
/// Default limit on total number of connected sockets
|
||||
static const int MAX_CONNECTIONS = INT_MAX;
|
||||
|
||||
/// Default limit on connections in handler/task processing
|
||||
static const int MAX_ACTIVE_PROCESSORS = INT_MAX;
|
||||
|
||||
/// Default size of write buffer
|
||||
static const int WRITE_BUFFER_DEFAULT_SIZE = 1024;
|
||||
|
||||
/// Maximum size of read buffer allocated to idle connection (0 = unlimited)
|
||||
static const int IDLE_READ_BUFFER_LIMIT = 1024;
|
||||
|
||||
/// Maximum size of write buffer allocated to idle connection (0 = unlimited)
|
||||
static const int IDLE_WRITE_BUFFER_LIMIT = 1024;
|
||||
|
||||
/// # of calls before resizing oversized buffers (0 = check only on close)
|
||||
static const int RESIZE_BUFFER_EVERY_N = 512;
|
||||
|
||||
/// # of IO threads to use by default
|
||||
static const int DEFAULT_IO_THREADS = 1;
|
||||
|
||||
/// # of IO threads this server will use
|
||||
size_t numIOThreads_;
|
||||
|
||||
/// Whether to set high scheduling priority for IO threads
|
||||
bool useHighPriorityIOThreads_;
|
||||
|
||||
/// Server socket file descriptor
|
||||
THRIFT_SOCKET serverSocket_;
|
||||
|
||||
/// Port server runs on. Zero when letting OS decide actual port
|
||||
int port_;
|
||||
|
||||
/// Port server actually runs on
|
||||
int listenPort_;
|
||||
|
||||
/// The optional user-provided event-base (for single-thread servers)
|
||||
event_base* userEventBase_;
|
||||
|
||||
/// For processing via thread pool, may be NULL
|
||||
boost::shared_ptr<ThreadManager> threadManager_;
|
||||
|
||||
/// Is thread pool processing?
|
||||
bool threadPoolProcessing_;
|
||||
|
||||
// Factory to create the IO threads
|
||||
boost::shared_ptr<PlatformThreadFactory> ioThreadFactory_;
|
||||
|
||||
// Vector of IOThread objects that will handle our IO
|
||||
std::vector<boost::shared_ptr<TNonblockingIOThread> > ioThreads_;
|
||||
|
||||
// Index of next IO Thread to be used (for round-robin)
|
||||
uint32_t nextIOThread_;
|
||||
|
||||
// Synchronizes access to connection stack and similar data
|
||||
Mutex connMutex_;
|
||||
|
||||
/// Number of TConnection object we've created
|
||||
size_t numTConnections_;
|
||||
|
||||
/// Number of Connections processing or waiting to process
|
||||
size_t numActiveProcessors_;
|
||||
|
||||
/// Limit for how many TConnection objects to cache
|
||||
size_t connectionStackLimit_;
|
||||
|
||||
/// Limit for number of connections processing or waiting to process
|
||||
size_t maxActiveProcessors_;
|
||||
|
||||
/// Limit for number of open connections
|
||||
size_t maxConnections_;
|
||||
|
||||
/// Limit for frame size
|
||||
size_t maxFrameSize_;
|
||||
|
||||
/// Time in milliseconds before an unperformed task expires (0 == infinite).
|
||||
int64_t taskExpireTime_;
|
||||
|
||||
/**
|
||||
* Hysteresis for overload state. This is the fraction of the overload
|
||||
* value that needs to be reached before the overload state is cleared;
|
||||
* must be <= 1.0.
|
||||
*/
|
||||
double overloadHysteresis_;
|
||||
|
||||
/// Action to take when we're overloaded.
|
||||
TOverloadAction overloadAction_;
|
||||
|
||||
/**
|
||||
* The write buffer is initialized (and when idleWriteBufferLimit_ is checked
|
||||
* and found to be exceeded, reinitialized) to this size.
|
||||
*/
|
||||
size_t writeBufferDefaultSize_;
|
||||
|
||||
/**
|
||||
* Max read buffer size for an idle TConnection. When we place an idle
|
||||
* TConnection into connectionStack_ or on every resizeBufferEveryN_ calls,
|
||||
* we will free the buffer (such that it will be reinitialized by the next
|
||||
* received frame) if it has exceeded this limit. 0 disables this check.
|
||||
*/
|
||||
size_t idleReadBufferLimit_;
|
||||
|
||||
/**
|
||||
* Max write buffer size for an idle connection. When we place an idle
|
||||
* TConnection into connectionStack_ or on every resizeBufferEveryN_ calls,
|
||||
* we insure that its write buffer is <= to this size; otherwise we
|
||||
* replace it with a new one of writeBufferDefaultSize_ bytes to insure that
|
||||
* idle connections don't hog memory. 0 disables this check.
|
||||
*/
|
||||
size_t idleWriteBufferLimit_;
|
||||
|
||||
/**
|
||||
* Every N calls we check the buffer size limits on a connected TConnection.
|
||||
* 0 disables (i.e. the checks are only done when a connection closes).
|
||||
*/
|
||||
int32_t resizeBufferEveryN_;
|
||||
|
||||
/// Set if we are currently in an overloaded state.
|
||||
bool overloaded_;
|
||||
|
||||
/// Count of connections dropped since overload started
|
||||
uint32_t nConnectionsDropped_;
|
||||
|
||||
/// Count of connections dropped on overload since server started
|
||||
uint64_t nTotalConnectionsDropped_;
|
||||
|
||||
/**
|
||||
* This is a stack of all the objects that have been created but that
|
||||
* are NOT currently in use. When we close a connection, we place it on this
|
||||
* stack so that the object can be reused later, rather than freeing the
|
||||
* memory and reallocating a new object later.
|
||||
*/
|
||||
std::stack<TConnection*> connectionStack_;
|
||||
|
||||
/**
|
||||
* This container holds pointers to all active connections. This container
|
||||
* allows the server to clean up unlcosed connection objects at destruction,
|
||||
* which in turn allows their transports, protocols, processors and handlers
|
||||
* to deallocate and clean up correctly.
|
||||
*/
|
||||
std::vector<TConnection*> activeConnections_;
|
||||
|
||||
/**
|
||||
* Called when server socket had something happen. We accept all waiting
|
||||
* client connections on listen socket fd and assign TConnection objects
|
||||
* to handle those requests.
|
||||
*
|
||||
* @param fd the listen socket.
|
||||
* @param which the event flag that triggered the handler.
|
||||
*/
|
||||
void handleEvent(THRIFT_SOCKET fd, short which);
|
||||
|
||||
void init(int port) {
|
||||
serverSocket_ = THRIFT_INVALID_SOCKET;
|
||||
numIOThreads_ = DEFAULT_IO_THREADS;
|
||||
nextIOThread_ = 0;
|
||||
useHighPriorityIOThreads_ = false;
|
||||
port_ = port;
|
||||
listenPort_ = port;
|
||||
userEventBase_ = NULL;
|
||||
threadPoolProcessing_ = false;
|
||||
numTConnections_ = 0;
|
||||
numActiveProcessors_ = 0;
|
||||
connectionStackLimit_ = CONNECTION_STACK_LIMIT;
|
||||
maxActiveProcessors_ = MAX_ACTIVE_PROCESSORS;
|
||||
maxConnections_ = MAX_CONNECTIONS;
|
||||
maxFrameSize_ = MAX_FRAME_SIZE;
|
||||
taskExpireTime_ = 0;
|
||||
overloadHysteresis_ = 0.8;
|
||||
overloadAction_ = T_OVERLOAD_NO_ACTION;
|
||||
writeBufferDefaultSize_ = WRITE_BUFFER_DEFAULT_SIZE;
|
||||
idleReadBufferLimit_ = IDLE_READ_BUFFER_LIMIT;
|
||||
idleWriteBufferLimit_ = IDLE_WRITE_BUFFER_LIMIT;
|
||||
resizeBufferEveryN_ = RESIZE_BUFFER_EVERY_N;
|
||||
overloaded_ = false;
|
||||
nConnectionsDropped_ = 0;
|
||||
nTotalConnectionsDropped_ = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
TNonblockingServer(const boost::shared_ptr<TProcessorFactory>& processorFactory, int port)
|
||||
: TServer(processorFactory) {
|
||||
init(port);
|
||||
}
|
||||
|
||||
TNonblockingServer(const boost::shared_ptr<TProcessor>& processor, int port)
|
||||
: TServer(processor) {
|
||||
init(port);
|
||||
}
|
||||
|
||||
TNonblockingServer(const boost::shared_ptr<TProcessorFactory>& processorFactory,
|
||||
const boost::shared_ptr<TProtocolFactory>& protocolFactory,
|
||||
int port,
|
||||
const boost::shared_ptr<ThreadManager>& threadManager
|
||||
= boost::shared_ptr<ThreadManager>())
|
||||
: TServer(processorFactory) {
|
||||
|
||||
init(port);
|
||||
|
||||
setInputProtocolFactory(protocolFactory);
|
||||
setOutputProtocolFactory(protocolFactory);
|
||||
setThreadManager(threadManager);
|
||||
}
|
||||
|
||||
TNonblockingServer(const boost::shared_ptr<TProcessor>& processor,
|
||||
const boost::shared_ptr<TProtocolFactory>& protocolFactory,
|
||||
int port,
|
||||
const boost::shared_ptr<ThreadManager>& threadManager
|
||||
= boost::shared_ptr<ThreadManager>())
|
||||
: TServer(processor) {
|
||||
|
||||
init(port);
|
||||
|
||||
setInputProtocolFactory(protocolFactory);
|
||||
setOutputProtocolFactory(protocolFactory);
|
||||
setThreadManager(threadManager);
|
||||
}
|
||||
|
||||
TNonblockingServer(const boost::shared_ptr<TProcessorFactory>& processorFactory,
|
||||
const boost::shared_ptr<TTransportFactory>& inputTransportFactory,
|
||||
const boost::shared_ptr<TTransportFactory>& outputTransportFactory,
|
||||
const boost::shared_ptr<TProtocolFactory>& inputProtocolFactory,
|
||||
const boost::shared_ptr<TProtocolFactory>& outputProtocolFactory,
|
||||
int port,
|
||||
const boost::shared_ptr<ThreadManager>& threadManager
|
||||
= boost::shared_ptr<ThreadManager>())
|
||||
: TServer(processorFactory) {
|
||||
|
||||
init(port);
|
||||
|
||||
setInputTransportFactory(inputTransportFactory);
|
||||
setOutputTransportFactory(outputTransportFactory);
|
||||
setInputProtocolFactory(inputProtocolFactory);
|
||||
setOutputProtocolFactory(outputProtocolFactory);
|
||||
setThreadManager(threadManager);
|
||||
}
|
||||
|
||||
TNonblockingServer(const boost::shared_ptr<TProcessor>& processor,
|
||||
const boost::shared_ptr<TTransportFactory>& inputTransportFactory,
|
||||
const boost::shared_ptr<TTransportFactory>& outputTransportFactory,
|
||||
const boost::shared_ptr<TProtocolFactory>& inputProtocolFactory,
|
||||
const boost::shared_ptr<TProtocolFactory>& outputProtocolFactory,
|
||||
int port,
|
||||
const boost::shared_ptr<ThreadManager>& threadManager
|
||||
= boost::shared_ptr<ThreadManager>())
|
||||
: TServer(processor) {
|
||||
|
||||
init(port);
|
||||
|
||||
setInputTransportFactory(inputTransportFactory);
|
||||
setOutputTransportFactory(outputTransportFactory);
|
||||
setInputProtocolFactory(inputProtocolFactory);
|
||||
setOutputProtocolFactory(outputProtocolFactory);
|
||||
setThreadManager(threadManager);
|
||||
}
|
||||
|
||||
~TNonblockingServer();
|
||||
|
||||
void setThreadManager(boost::shared_ptr<ThreadManager> threadManager);
|
||||
|
||||
int getListenPort() { return listenPort_; }
|
||||
|
||||
boost::shared_ptr<ThreadManager> getThreadManager() { return threadManager_; }
|
||||
|
||||
/**
|
||||
* Sets the number of IO threads used by this server. Can only be used before
|
||||
* the call to serve() and has no effect afterwards. We always use a
|
||||
* PosixThreadFactory for the IO worker threads, because they must joinable
|
||||
* for clean shutdown.
|
||||
*/
|
||||
void setNumIOThreads(size_t numThreads) {
|
||||
numIOThreads_ = numThreads;
|
||||
// User-provided event-base doesn't works for multi-threaded servers
|
||||
assert(numIOThreads_ <= 1 || !userEventBase_);
|
||||
}
|
||||
|
||||
/** Return whether the IO threads will get high scheduling priority */
|
||||
bool useHighPriorityIOThreads() const { return useHighPriorityIOThreads_; }
|
||||
|
||||
/** Set whether the IO threads will get high scheduling priority. */
|
||||
void setUseHighPriorityIOThreads(bool val) { useHighPriorityIOThreads_ = val; }
|
||||
|
||||
/** Return the number of IO threads used by this server. */
|
||||
size_t getNumIOThreads() const { return numIOThreads_; }
|
||||
|
||||
/**
|
||||
* Get the maximum number of unused TConnection we will hold in reserve.
|
||||
*
|
||||
* @return the current limit on TConnection pool size.
|
||||
*/
|
||||
size_t getConnectionStackLimit() const { return connectionStackLimit_; }
|
||||
|
||||
/**
|
||||
* Set the maximum number of unused TConnection we will hold in reserve.
|
||||
*
|
||||
* @param sz the new limit for TConnection pool size.
|
||||
*/
|
||||
void setConnectionStackLimit(size_t sz) { connectionStackLimit_ = sz; }
|
||||
|
||||
bool isThreadPoolProcessing() const { return threadPoolProcessing_; }
|
||||
|
||||
void addTask(boost::shared_ptr<Runnable> task) {
|
||||
threadManager_->add(task, 0LL, taskExpireTime_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the count of sockets currently connected to.
|
||||
*
|
||||
* @return count of connected sockets.
|
||||
*/
|
||||
size_t getNumConnections() const { return numTConnections_; }
|
||||
|
||||
/**
|
||||
* Return the count of sockets currently connected to.
|
||||
*
|
||||
* @return count of connected sockets.
|
||||
*/
|
||||
size_t getNumActiveConnections() const { return getNumConnections() - getNumIdleConnections(); }
|
||||
|
||||
/**
|
||||
* Return the count of connection objects allocated but not in use.
|
||||
*
|
||||
* @return count of idle connection objects.
|
||||
*/
|
||||
size_t getNumIdleConnections() const { return connectionStack_.size(); }
|
||||
|
||||
/**
|
||||
* Return count of number of connections which are currently processing.
|
||||
* This is defined as a connection where all data has been received and
|
||||
* either assigned a task (when threading) or passed to a handler (when
|
||||
* not threading), and where the handler has not yet returned.
|
||||
*
|
||||
* @return # of connections currently processing.
|
||||
*/
|
||||
size_t getNumActiveProcessors() const { return numActiveProcessors_; }
|
||||
|
||||
/// Increment the count of connections currently processing.
|
||||
void incrementActiveProcessors() {
|
||||
Guard g(connMutex_);
|
||||
++numActiveProcessors_;
|
||||
}
|
||||
|
||||
/// Decrement the count of connections currently processing.
|
||||
void decrementActiveProcessors() {
|
||||
Guard g(connMutex_);
|
||||
if (numActiveProcessors_ > 0) {
|
||||
--numActiveProcessors_;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum # of connections allowed before overload.
|
||||
*
|
||||
* @return current setting.
|
||||
*/
|
||||
size_t getMaxConnections() const { return maxConnections_; }
|
||||
|
||||
/**
|
||||
* Set the maximum # of connections allowed before overload.
|
||||
*
|
||||
* @param maxConnections new setting for maximum # of connections.
|
||||
*/
|
||||
void setMaxConnections(size_t maxConnections) { maxConnections_ = maxConnections; }
|
||||
|
||||
/**
|
||||
* Get the maximum # of connections waiting in handler/task before overload.
|
||||
*
|
||||
* @return current setting.
|
||||
*/
|
||||
size_t getMaxActiveProcessors() const { return maxActiveProcessors_; }
|
||||
|
||||
/**
|
||||
* Set the maximum # of connections waiting in handler/task before overload.
|
||||
*
|
||||
* @param maxActiveProcessors new setting for maximum # of active processes.
|
||||
*/
|
||||
void setMaxActiveProcessors(size_t maxActiveProcessors) {
|
||||
maxActiveProcessors_ = maxActiveProcessors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum allowed frame size.
|
||||
*
|
||||
* If a client tries to send a message larger than this limit,
|
||||
* its connection will be closed.
|
||||
*
|
||||
* @return Maxium frame size, in bytes.
|
||||
*/
|
||||
size_t getMaxFrameSize() const { return maxFrameSize_; }
|
||||
|
||||
/**
|
||||
* Set the maximum allowed frame size.
|
||||
*
|
||||
* @param maxFrameSize The new maximum frame size.
|
||||
*/
|
||||
void setMaxFrameSize(size_t maxFrameSize) { maxFrameSize_ = maxFrameSize; }
|
||||
|
||||
/**
|
||||
* Get fraction of maximum limits before an overload condition is cleared.
|
||||
*
|
||||
* @return hysteresis fraction
|
||||
*/
|
||||
double getOverloadHysteresis() const { return overloadHysteresis_; }
|
||||
|
||||
/**
|
||||
* Set fraction of maximum limits before an overload condition is cleared.
|
||||
* A good value would probably be between 0.5 and 0.9.
|
||||
*
|
||||
* @param hysteresisFraction fraction <= 1.0.
|
||||
*/
|
||||
void setOverloadHysteresis(double hysteresisFraction) {
|
||||
if (hysteresisFraction <= 1.0 && hysteresisFraction > 0.0) {
|
||||
overloadHysteresis_ = hysteresisFraction;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the action the server will take on overload.
|
||||
*
|
||||
* @return a TOverloadAction enum value for the currently set action.
|
||||
*/
|
||||
TOverloadAction getOverloadAction() const { return overloadAction_; }
|
||||
|
||||
/**
|
||||
* Set the action the server is to take on overload.
|
||||
*
|
||||
* @param overloadAction a TOverloadAction enum value for the action.
|
||||
*/
|
||||
void setOverloadAction(TOverloadAction overloadAction) { overloadAction_ = overloadAction; }
|
||||
|
||||
/**
|
||||
* Get the time in milliseconds after which a task expires (0 == infinite).
|
||||
*
|
||||
* @return a 64-bit time in milliseconds.
|
||||
*/
|
||||
int64_t getTaskExpireTime() const { return taskExpireTime_; }
|
||||
|
||||
/**
|
||||
* Set the time in milliseconds after which a task expires (0 == infinite).
|
||||
*
|
||||
* @param taskExpireTime a 64-bit time in milliseconds.
|
||||
*/
|
||||
void setTaskExpireTime(int64_t taskExpireTime) { taskExpireTime_ = taskExpireTime; }
|
||||
|
||||
/**
|
||||
* Determine if the server is currently overloaded.
|
||||
* This function checks the maximums for open connections and connections
|
||||
* currently in processing, and sets an overload condition if they are
|
||||
* exceeded. The overload will persist until both values are below the
|
||||
* current hysteresis fraction of their maximums.
|
||||
*
|
||||
* @return true if an overload condition exists, false if not.
|
||||
*/
|
||||
bool serverOverloaded();
|
||||
|
||||
/** Pop and discard next task on threadpool wait queue.
|
||||
*
|
||||
* @return true if a task was discarded, false if the wait queue was empty.
|
||||
*/
|
||||
bool drainPendingTask();
|
||||
|
||||
/**
|
||||
* Get the starting size of a TConnection object's write buffer.
|
||||
*
|
||||
* @return # bytes we initialize a TConnection object's write buffer to.
|
||||
*/
|
||||
size_t getWriteBufferDefaultSize() const { return writeBufferDefaultSize_; }
|
||||
|
||||
/**
|
||||
* Set the starting size of a TConnection object's write buffer.
|
||||
*
|
||||
* @param size # bytes we initialize a TConnection object's write buffer to.
|
||||
*/
|
||||
void setWriteBufferDefaultSize(size_t size) { writeBufferDefaultSize_ = size; }
|
||||
|
||||
/**
|
||||
* Get the maximum size of read buffer allocated to idle TConnection objects.
|
||||
*
|
||||
* @return # bytes beyond which we will dealloc idle buffer.
|
||||
*/
|
||||
size_t getIdleReadBufferLimit() const { return idleReadBufferLimit_; }
|
||||
|
||||
/**
|
||||
* [NOTE: This is for backwards compatibility, use getIdleReadBufferLimit().]
|
||||
* Get the maximum size of read buffer allocated to idle TConnection objects.
|
||||
*
|
||||
* @return # bytes beyond which we will dealloc idle buffer.
|
||||
*/
|
||||
size_t getIdleBufferMemLimit() const { return idleReadBufferLimit_; }
|
||||
|
||||
/**
|
||||
* Set the maximum size read buffer allocated to idle TConnection objects.
|
||||
* If a TConnection object is found (either on connection close or between
|
||||
* calls when resizeBufferEveryN_ is set) with more than this much memory
|
||||
* allocated to its read buffer, we free it and allow it to be reinitialized
|
||||
* on the next received frame.
|
||||
*
|
||||
* @param limit of bytes beyond which we will shrink buffers when checked.
|
||||
*/
|
||||
void setIdleReadBufferLimit(size_t limit) { idleReadBufferLimit_ = limit; }
|
||||
|
||||
/**
|
||||
* [NOTE: This is for backwards compatibility, use setIdleReadBufferLimit().]
|
||||
* Set the maximum size read buffer allocated to idle TConnection objects.
|
||||
* If a TConnection object is found (either on connection close or between
|
||||
* calls when resizeBufferEveryN_ is set) with more than this much memory
|
||||
* allocated to its read buffer, we free it and allow it to be reinitialized
|
||||
* on the next received frame.
|
||||
*
|
||||
* @param limit of bytes beyond which we will shrink buffers when checked.
|
||||
*/
|
||||
void setIdleBufferMemLimit(size_t limit) { idleReadBufferLimit_ = limit; }
|
||||
|
||||
/**
|
||||
* Get the maximum size of write buffer allocated to idle TConnection objects.
|
||||
*
|
||||
* @return # bytes beyond which we will reallocate buffers when checked.
|
||||
*/
|
||||
size_t getIdleWriteBufferLimit() const { return idleWriteBufferLimit_; }
|
||||
|
||||
/**
|
||||
* Set the maximum size write buffer allocated to idle TConnection objects.
|
||||
* If a TConnection object is found (either on connection close or between
|
||||
* calls when resizeBufferEveryN_ is set) with more than this much memory
|
||||
* allocated to its write buffer, we destroy and construct that buffer with
|
||||
* writeBufferDefaultSize_ bytes.
|
||||
*
|
||||
* @param limit of bytes beyond which we will shrink buffers when idle.
|
||||
*/
|
||||
void setIdleWriteBufferLimit(size_t limit) { idleWriteBufferLimit_ = limit; }
|
||||
|
||||
/**
|
||||
* Get # of calls made between buffer size checks. 0 means disabled.
|
||||
*
|
||||
* @return # of calls between buffer size checks.
|
||||
*/
|
||||
int32_t getResizeBufferEveryN() const { return resizeBufferEveryN_; }
|
||||
|
||||
/**
|
||||
* Check buffer sizes every "count" calls. This allows buffer limits
|
||||
* to be enforced for persistent connections with a controllable degree
|
||||
* of overhead. 0 disables checks except at connection close.
|
||||
*
|
||||
* @param count the number of calls between checks, or 0 to disable
|
||||
*/
|
||||
void setResizeBufferEveryN(int32_t count) { resizeBufferEveryN_ = count; }
|
||||
|
||||
/**
|
||||
* Main workhorse function, starts up the server listening on a port and
|
||||
* loops over the libevent handler.
|
||||
*/
|
||||
void serve();
|
||||
|
||||
/**
|
||||
* Causes the server to terminate gracefully (can be called from any thread).
|
||||
*/
|
||||
void stop();
|
||||
|
||||
/// Creates a socket to listen on and binds it to the local port.
|
||||
void createAndListenOnSocket();
|
||||
|
||||
/**
|
||||
* Takes a socket created by createAndListenOnSocket() and sets various
|
||||
* options on it to prepare for use in the server.
|
||||
*
|
||||
* @param fd descriptor of socket to be initialized/
|
||||
*/
|
||||
void listenSocket(THRIFT_SOCKET fd);
|
||||
|
||||
/**
|
||||
* Register the optional user-provided event-base (for single-thread servers)
|
||||
*
|
||||
* This method should be used when the server is running in a single-thread
|
||||
* mode, and the event base is provided by the user (i.e., the caller).
|
||||
*
|
||||
* @param user_event_base the user-provided event-base. The user is
|
||||
* responsible for freeing the event base memory.
|
||||
*/
|
||||
void registerEvents(event_base* user_event_base);
|
||||
|
||||
/**
|
||||
* Returns the optional user-provided event-base (for single-thread servers).
|
||||
*/
|
||||
event_base* getUserEventBase() const { return userEventBase_; }
|
||||
|
||||
/** Some transports, like THeaderTransport, require passing through
|
||||
* the framing size instead of stripping it.
|
||||
*/
|
||||
bool getHeaderTransport();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Callback function that the threadmanager calls when a task reaches
|
||||
* its expiration time. It is needed to clean up the expired connection.
|
||||
*
|
||||
* @param task the runnable associated with the expired task.
|
||||
*/
|
||||
void expireClose(boost::shared_ptr<Runnable> task);
|
||||
|
||||
/**
|
||||
* Return an initialized connection object. Creates or recovers from
|
||||
* pool a TConnection and initializes it with the provided socket FD
|
||||
* and flags.
|
||||
*
|
||||
* @param socket FD of socket associated with this connection.
|
||||
* @param addr the sockaddr of the client
|
||||
* @param addrLen the length of addr
|
||||
* @return pointer to initialized TConnection object.
|
||||
*/
|
||||
TConnection* createConnection(THRIFT_SOCKET socket, const sockaddr* addr, socklen_t addrLen);
|
||||
|
||||
/**
|
||||
* Returns a connection to pool or deletion. If the connection pool
|
||||
* (a stack) isn't full, place the connection object on it, otherwise
|
||||
* just delete it.
|
||||
*
|
||||
* @param connection the TConection being returned.
|
||||
*/
|
||||
void returnConnection(TConnection* connection);
|
||||
};
|
||||
|
||||
class TNonblockingIOThread : public Runnable {
|
||||
public:
|
||||
// Creates an IO thread and sets up the event base. The listenSocket should
|
||||
// be a valid FD on which listen() has already been called. If the
|
||||
// listenSocket is < 0, accepting will not be done.
|
||||
TNonblockingIOThread(TNonblockingServer* server,
|
||||
int number,
|
||||
THRIFT_SOCKET listenSocket,
|
||||
bool useHighPriority);
|
||||
|
||||
~TNonblockingIOThread();
|
||||
|
||||
// Returns the event-base for this thread.
|
||||
event_base* getEventBase() const { return eventBase_; }
|
||||
|
||||
// Returns the server for this thread.
|
||||
TNonblockingServer* getServer() const { return server_; }
|
||||
|
||||
// Returns the number of this IO thread.
|
||||
int getThreadNumber() const { return number_; }
|
||||
|
||||
// Returns the thread id associated with this object. This should
|
||||
// only be called after the thread has been started.
|
||||
Thread::id_t getThreadId() const { return threadId_; }
|
||||
|
||||
// Returns the send-fd for task complete notifications.
|
||||
evutil_socket_t getNotificationSendFD() const { return notificationPipeFDs_[1]; }
|
||||
|
||||
// Returns the read-fd for task complete notifications.
|
||||
evutil_socket_t getNotificationRecvFD() const { return notificationPipeFDs_[0]; }
|
||||
|
||||
// Returns the actual thread object associated with this IO thread.
|
||||
boost::shared_ptr<Thread> getThread() const { return thread_; }
|
||||
|
||||
// Sets the actual thread object associated with this IO thread.
|
||||
void setThread(const boost::shared_ptr<Thread>& t) { thread_ = t; }
|
||||
|
||||
// Used by TConnection objects to indicate processing has finished.
|
||||
bool notify(TNonblockingServer::TConnection* conn);
|
||||
|
||||
// Enters the event loop and does not return until a call to stop().
|
||||
virtual void run();
|
||||
|
||||
// Exits the event loop as soon as possible.
|
||||
void stop();
|
||||
|
||||
// Ensures that the event-loop thread is fully finished and shut down.
|
||||
void join();
|
||||
|
||||
/// Registers the events for the notification & listen sockets
|
||||
void registerEvents();
|
||||
|
||||
private:
|
||||
/**
|
||||
* C-callable event handler for signaling task completion. Provides a
|
||||
* callback that libevent can understand that will read a connection
|
||||
* object's address from a pipe and call connection->transition() for
|
||||
* that object.
|
||||
*
|
||||
* @param fd the descriptor the event occurred on.
|
||||
*/
|
||||
static void notifyHandler(evutil_socket_t fd, short which, void* v);
|
||||
|
||||
/**
|
||||
* C-callable event handler for listener events. Provides a callback
|
||||
* that libevent can understand which invokes server->handleEvent().
|
||||
*
|
||||
* @param fd the descriptor the event occurred on.
|
||||
* @param which the flags associated with the event.
|
||||
* @param v void* callback arg where we placed TNonblockingServer's "this".
|
||||
*/
|
||||
static void listenHandler(evutil_socket_t fd, short which, void* v) {
|
||||
((TNonblockingServer*)v)->handleEvent(fd, which);
|
||||
}
|
||||
|
||||
/// Exits the loop ASAP in case of shutdown or error.
|
||||
void breakLoop(bool error);
|
||||
|
||||
/// Create the pipe used to notify I/O process of task completion.
|
||||
void createNotificationPipe();
|
||||
|
||||
/// Unregisters our events for notification and listen sockets.
|
||||
void cleanupEvents();
|
||||
|
||||
/// Sets (or clears) high priority scheduling status for the current thread.
|
||||
void setCurrentThreadHighPriority(bool value);
|
||||
|
||||
private:
|
||||
/// associated server
|
||||
TNonblockingServer* server_;
|
||||
|
||||
/// thread number (for debugging).
|
||||
const int number_;
|
||||
|
||||
/// The actual physical thread id.
|
||||
Thread::id_t threadId_;
|
||||
|
||||
/// If listenSocket_ >= 0, adds an event on the event_base to accept conns
|
||||
THRIFT_SOCKET listenSocket_;
|
||||
|
||||
/// Sets a high scheduling priority when running
|
||||
bool useHighPriority_;
|
||||
|
||||
/// pointer to eventbase to be used for looping
|
||||
event_base* eventBase_;
|
||||
|
||||
/// Set to true if this class is responsible for freeing the event base
|
||||
/// memory.
|
||||
bool ownEventBase_;
|
||||
|
||||
/// Used with eventBase_ for connection events (only in listener thread)
|
||||
struct event serverEvent_;
|
||||
|
||||
/// Used with eventBase_ for task completion notification
|
||||
struct event notificationEvent_;
|
||||
|
||||
/// File descriptors for pipe used for task completion notification.
|
||||
evutil_socket_t notificationPipeFDs_[2];
|
||||
|
||||
/// Actual IO Thread
|
||||
boost::shared_ptr<Thread> thread_;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::server
|
||||
|
||||
#endif // #ifndef _THRIFT_SERVER_TNONBLOCKINGSERVER_H_
|
52
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TServer.cpp
generated
vendored
Normal file
52
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TServer.cpp
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/thrift-config.h>
|
||||
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace server {
|
||||
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
int increase_max_fds(int max_fds = (1 << 24)) {
|
||||
struct rlimit fdmaxrl;
|
||||
|
||||
for (fdmaxrl.rlim_cur = max_fds, fdmaxrl.rlim_max = max_fds;
|
||||
max_fds && (setrlimit(RLIMIT_NOFILE, &fdmaxrl) < 0);
|
||||
fdmaxrl.rlim_cur = max_fds, fdmaxrl.rlim_max = max_fds) {
|
||||
max_fds /= 2;
|
||||
}
|
||||
|
||||
return static_cast<int>(fdmaxrl.rlim_cur);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} // apache::thrift::server
|
273
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TServer.h
generated
vendored
Normal file
273
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TServer.h
generated
vendored
Normal file
|
@ -0,0 +1,273 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_SERVER_TSERVER_H_
|
||||
#define _THRIFT_SERVER_TSERVER_H_ 1
|
||||
|
||||
#include <thrift/TProcessor.h>
|
||||
#include <thrift/transport/TServerTransport.h>
|
||||
#include <thrift/protocol/TBinaryProtocol.h>
|
||||
#include <thrift/concurrency/Thread.h>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace server {
|
||||
|
||||
using apache::thrift::TProcessor;
|
||||
using apache::thrift::protocol::TBinaryProtocolFactory;
|
||||
using apache::thrift::protocol::TProtocol;
|
||||
using apache::thrift::protocol::TProtocolFactory;
|
||||
using apache::thrift::transport::TServerTransport;
|
||||
using apache::thrift::transport::TTransport;
|
||||
using apache::thrift::transport::TTransportFactory;
|
||||
|
||||
/**
|
||||
* Virtual interface class that can handle events from the server core. To
|
||||
* use this you should subclass it and implement the methods that you care
|
||||
* about. Your subclass can also store local data that you may care about,
|
||||
* such as additional "arguments" to these methods (stored in the object
|
||||
* instance's state).
|
||||
*/
|
||||
class TServerEventHandler {
|
||||
public:
|
||||
virtual ~TServerEventHandler() {}
|
||||
|
||||
/**
|
||||
* Called before the server begins.
|
||||
*/
|
||||
virtual void preServe() {}
|
||||
|
||||
/**
|
||||
* Called when a new client has connected and is about to being processing.
|
||||
*/
|
||||
virtual void* createContext(boost::shared_ptr<TProtocol> input,
|
||||
boost::shared_ptr<TProtocol> output) {
|
||||
(void)input;
|
||||
(void)output;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a client has finished request-handling to delete server
|
||||
* context.
|
||||
*/
|
||||
virtual void deleteContext(void* serverContext,
|
||||
boost::shared_ptr<TProtocol> input,
|
||||
boost::shared_ptr<TProtocol> output) {
|
||||
(void)serverContext;
|
||||
(void)input;
|
||||
(void)output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a client is about to call the processor.
|
||||
*/
|
||||
virtual void processContext(void* serverContext, boost::shared_ptr<TTransport> transport) {
|
||||
(void)serverContext;
|
||||
(void)transport;
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Prevent direct instantiation.
|
||||
*/
|
||||
TServerEventHandler() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Thrift server.
|
||||
*
|
||||
*/
|
||||
class TServer : public concurrency::Runnable {
|
||||
public:
|
||||
virtual ~TServer() {}
|
||||
|
||||
virtual void serve() = 0;
|
||||
|
||||
virtual void stop() {}
|
||||
|
||||
// Allows running the server as a Runnable thread
|
||||
virtual void run() { serve(); }
|
||||
|
||||
boost::shared_ptr<TProcessorFactory> getProcessorFactory() { return processorFactory_; }
|
||||
|
||||
boost::shared_ptr<TServerTransport> getServerTransport() { return serverTransport_; }
|
||||
|
||||
boost::shared_ptr<TTransportFactory> getInputTransportFactory() { return inputTransportFactory_; }
|
||||
|
||||
boost::shared_ptr<TTransportFactory> getOutputTransportFactory() {
|
||||
return outputTransportFactory_;
|
||||
}
|
||||
|
||||
boost::shared_ptr<TProtocolFactory> getInputProtocolFactory() { return inputProtocolFactory_; }
|
||||
|
||||
boost::shared_ptr<TProtocolFactory> getOutputProtocolFactory() { return outputProtocolFactory_; }
|
||||
|
||||
boost::shared_ptr<TServerEventHandler> getEventHandler() { return eventHandler_; }
|
||||
|
||||
protected:
|
||||
TServer(const boost::shared_ptr<TProcessorFactory>& processorFactory)
|
||||
: processorFactory_(processorFactory) {
|
||||
setInputTransportFactory(boost::shared_ptr<TTransportFactory>(new TTransportFactory()));
|
||||
setOutputTransportFactory(boost::shared_ptr<TTransportFactory>(new TTransportFactory()));
|
||||
setInputProtocolFactory(boost::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
|
||||
setOutputProtocolFactory(boost::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
|
||||
}
|
||||
|
||||
TServer(const boost::shared_ptr<TProcessor>& processor)
|
||||
: processorFactory_(new TSingletonProcessorFactory(processor)) {
|
||||
setInputTransportFactory(boost::shared_ptr<TTransportFactory>(new TTransportFactory()));
|
||||
setOutputTransportFactory(boost::shared_ptr<TTransportFactory>(new TTransportFactory()));
|
||||
setInputProtocolFactory(boost::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
|
||||
setOutputProtocolFactory(boost::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
|
||||
}
|
||||
|
||||
TServer(const boost::shared_ptr<TProcessorFactory>& processorFactory,
|
||||
const boost::shared_ptr<TServerTransport>& serverTransport)
|
||||
: processorFactory_(processorFactory), serverTransport_(serverTransport) {
|
||||
setInputTransportFactory(boost::shared_ptr<TTransportFactory>(new TTransportFactory()));
|
||||
setOutputTransportFactory(boost::shared_ptr<TTransportFactory>(new TTransportFactory()));
|
||||
setInputProtocolFactory(boost::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
|
||||
setOutputProtocolFactory(boost::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
|
||||
}
|
||||
|
||||
TServer(const boost::shared_ptr<TProcessor>& processor,
|
||||
const boost::shared_ptr<TServerTransport>& serverTransport)
|
||||
: processorFactory_(new TSingletonProcessorFactory(processor)),
|
||||
serverTransport_(serverTransport) {
|
||||
setInputTransportFactory(boost::shared_ptr<TTransportFactory>(new TTransportFactory()));
|
||||
setOutputTransportFactory(boost::shared_ptr<TTransportFactory>(new TTransportFactory()));
|
||||
setInputProtocolFactory(boost::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
|
||||
setOutputProtocolFactory(boost::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
|
||||
}
|
||||
|
||||
TServer(const boost::shared_ptr<TProcessorFactory>& processorFactory,
|
||||
const boost::shared_ptr<TServerTransport>& serverTransport,
|
||||
const boost::shared_ptr<TTransportFactory>& transportFactory,
|
||||
const boost::shared_ptr<TProtocolFactory>& protocolFactory)
|
||||
: processorFactory_(processorFactory),
|
||||
serverTransport_(serverTransport),
|
||||
inputTransportFactory_(transportFactory),
|
||||
outputTransportFactory_(transportFactory),
|
||||
inputProtocolFactory_(protocolFactory),
|
||||
outputProtocolFactory_(protocolFactory) {}
|
||||
|
||||
TServer(const boost::shared_ptr<TProcessor>& processor,
|
||||
const boost::shared_ptr<TServerTransport>& serverTransport,
|
||||
const boost::shared_ptr<TTransportFactory>& transportFactory,
|
||||
const boost::shared_ptr<TProtocolFactory>& protocolFactory)
|
||||
: processorFactory_(new TSingletonProcessorFactory(processor)),
|
||||
serverTransport_(serverTransport),
|
||||
inputTransportFactory_(transportFactory),
|
||||
outputTransportFactory_(transportFactory),
|
||||
inputProtocolFactory_(protocolFactory),
|
||||
outputProtocolFactory_(protocolFactory) {}
|
||||
|
||||
TServer(const boost::shared_ptr<TProcessorFactory>& processorFactory,
|
||||
const boost::shared_ptr<TServerTransport>& serverTransport,
|
||||
const boost::shared_ptr<TTransportFactory>& inputTransportFactory,
|
||||
const boost::shared_ptr<TTransportFactory>& outputTransportFactory,
|
||||
const boost::shared_ptr<TProtocolFactory>& inputProtocolFactory,
|
||||
const boost::shared_ptr<TProtocolFactory>& outputProtocolFactory)
|
||||
: processorFactory_(processorFactory),
|
||||
serverTransport_(serverTransport),
|
||||
inputTransportFactory_(inputTransportFactory),
|
||||
outputTransportFactory_(outputTransportFactory),
|
||||
inputProtocolFactory_(inputProtocolFactory),
|
||||
outputProtocolFactory_(outputProtocolFactory) {}
|
||||
|
||||
TServer(const boost::shared_ptr<TProcessor>& processor,
|
||||
const boost::shared_ptr<TServerTransport>& serverTransport,
|
||||
const boost::shared_ptr<TTransportFactory>& inputTransportFactory,
|
||||
const boost::shared_ptr<TTransportFactory>& outputTransportFactory,
|
||||
const boost::shared_ptr<TProtocolFactory>& inputProtocolFactory,
|
||||
const boost::shared_ptr<TProtocolFactory>& outputProtocolFactory)
|
||||
: processorFactory_(new TSingletonProcessorFactory(processor)),
|
||||
serverTransport_(serverTransport),
|
||||
inputTransportFactory_(inputTransportFactory),
|
||||
outputTransportFactory_(outputTransportFactory),
|
||||
inputProtocolFactory_(inputProtocolFactory),
|
||||
outputProtocolFactory_(outputProtocolFactory) {}
|
||||
|
||||
/**
|
||||
* Get a TProcessor to handle calls on a particular connection.
|
||||
*
|
||||
* This method should only be called once per connection (never once per
|
||||
* call). This allows the TProcessorFactory to return a different processor
|
||||
* for each connection if it desires.
|
||||
*/
|
||||
boost::shared_ptr<TProcessor> getProcessor(boost::shared_ptr<TProtocol> inputProtocol,
|
||||
boost::shared_ptr<TProtocol> outputProtocol,
|
||||
boost::shared_ptr<TTransport> transport) {
|
||||
TConnectionInfo connInfo;
|
||||
connInfo.input = inputProtocol;
|
||||
connInfo.output = outputProtocol;
|
||||
connInfo.transport = transport;
|
||||
return processorFactory_->getProcessor(connInfo);
|
||||
}
|
||||
|
||||
// Class variables
|
||||
boost::shared_ptr<TProcessorFactory> processorFactory_;
|
||||
boost::shared_ptr<TServerTransport> serverTransport_;
|
||||
|
||||
boost::shared_ptr<TTransportFactory> inputTransportFactory_;
|
||||
boost::shared_ptr<TTransportFactory> outputTransportFactory_;
|
||||
|
||||
boost::shared_ptr<TProtocolFactory> inputProtocolFactory_;
|
||||
boost::shared_ptr<TProtocolFactory> outputProtocolFactory_;
|
||||
|
||||
boost::shared_ptr<TServerEventHandler> eventHandler_;
|
||||
|
||||
public:
|
||||
void setInputTransportFactory(boost::shared_ptr<TTransportFactory> inputTransportFactory) {
|
||||
inputTransportFactory_ = inputTransportFactory;
|
||||
}
|
||||
|
||||
void setOutputTransportFactory(boost::shared_ptr<TTransportFactory> outputTransportFactory) {
|
||||
outputTransportFactory_ = outputTransportFactory;
|
||||
}
|
||||
|
||||
void setInputProtocolFactory(boost::shared_ptr<TProtocolFactory> inputProtocolFactory) {
|
||||
inputProtocolFactory_ = inputProtocolFactory;
|
||||
}
|
||||
|
||||
void setOutputProtocolFactory(boost::shared_ptr<TProtocolFactory> outputProtocolFactory) {
|
||||
outputProtocolFactory_ = outputProtocolFactory;
|
||||
}
|
||||
|
||||
void setServerEventHandler(boost::shared_ptr<TServerEventHandler> eventHandler) {
|
||||
eventHandler_ = eventHandler;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function to increase the max file descriptors limit
|
||||
* for the current process and all of its children.
|
||||
* By default, tries to increase it to as much as 2^24.
|
||||
*/
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
int increase_max_fds(int max_fds = (1 << 24));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} // apache::thrift::server
|
||||
|
||||
#endif // #ifndef _THRIFT_SERVER_TSERVER_H_
|
246
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TServerFramework.cpp
generated
vendored
Normal file
246
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TServerFramework.cpp
generated
vendored
Normal file
|
@ -0,0 +1,246 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/bind.hpp>
|
||||
#include <stdexcept>
|
||||
#include <stdint.h>
|
||||
#include <thrift/server/TServerFramework.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace server {
|
||||
|
||||
using apache::thrift::concurrency::Synchronized;
|
||||
using apache::thrift::transport::TServerTransport;
|
||||
using apache::thrift::transport::TTransport;
|
||||
using apache::thrift::transport::TTransportException;
|
||||
using apache::thrift::transport::TTransportFactory;
|
||||
using apache::thrift::protocol::TProtocol;
|
||||
using apache::thrift::protocol::TProtocolFactory;
|
||||
using boost::bind;
|
||||
using boost::shared_ptr;
|
||||
using std::string;
|
||||
|
||||
TServerFramework::TServerFramework(const shared_ptr<TProcessorFactory>& processorFactory,
|
||||
const shared_ptr<TServerTransport>& serverTransport,
|
||||
const shared_ptr<TTransportFactory>& transportFactory,
|
||||
const shared_ptr<TProtocolFactory>& protocolFactory)
|
||||
: TServer(processorFactory, serverTransport, transportFactory, protocolFactory),
|
||||
clients_(0),
|
||||
hwm_(0),
|
||||
limit_(INT64_MAX) {
|
||||
}
|
||||
|
||||
TServerFramework::TServerFramework(const shared_ptr<TProcessor>& processor,
|
||||
const shared_ptr<TServerTransport>& serverTransport,
|
||||
const shared_ptr<TTransportFactory>& transportFactory,
|
||||
const shared_ptr<TProtocolFactory>& protocolFactory)
|
||||
: TServer(processor, serverTransport, transportFactory, protocolFactory),
|
||||
clients_(0),
|
||||
hwm_(0),
|
||||
limit_(INT64_MAX) {
|
||||
}
|
||||
|
||||
TServerFramework::TServerFramework(const shared_ptr<TProcessorFactory>& processorFactory,
|
||||
const shared_ptr<TServerTransport>& serverTransport,
|
||||
const shared_ptr<TTransportFactory>& inputTransportFactory,
|
||||
const shared_ptr<TTransportFactory>& outputTransportFactory,
|
||||
const shared_ptr<TProtocolFactory>& inputProtocolFactory,
|
||||
const shared_ptr<TProtocolFactory>& outputProtocolFactory)
|
||||
: TServer(processorFactory,
|
||||
serverTransport,
|
||||
inputTransportFactory,
|
||||
outputTransportFactory,
|
||||
inputProtocolFactory,
|
||||
outputProtocolFactory),
|
||||
clients_(0),
|
||||
hwm_(0),
|
||||
limit_(INT64_MAX) {
|
||||
}
|
||||
|
||||
TServerFramework::TServerFramework(const shared_ptr<TProcessor>& processor,
|
||||
const shared_ptr<TServerTransport>& serverTransport,
|
||||
const shared_ptr<TTransportFactory>& inputTransportFactory,
|
||||
const shared_ptr<TTransportFactory>& outputTransportFactory,
|
||||
const shared_ptr<TProtocolFactory>& inputProtocolFactory,
|
||||
const shared_ptr<TProtocolFactory>& outputProtocolFactory)
|
||||
: TServer(processor,
|
||||
serverTransport,
|
||||
inputTransportFactory,
|
||||
outputTransportFactory,
|
||||
inputProtocolFactory,
|
||||
outputProtocolFactory),
|
||||
clients_(0),
|
||||
hwm_(0),
|
||||
limit_(INT64_MAX) {
|
||||
}
|
||||
|
||||
TServerFramework::~TServerFramework() {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void releaseOneDescriptor(const string& name, T& pTransport) {
|
||||
if (pTransport) {
|
||||
try {
|
||||
pTransport->close();
|
||||
} catch (const TTransportException& ttx) {
|
||||
string errStr = string("TServerFramework " + name + " close failed: ") + ttx.what();
|
||||
GlobalOutput(errStr.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TServerFramework::serve() {
|
||||
shared_ptr<TTransport> client;
|
||||
shared_ptr<TTransport> inputTransport;
|
||||
shared_ptr<TTransport> outputTransport;
|
||||
shared_ptr<TProtocol> inputProtocol;
|
||||
shared_ptr<TProtocol> outputProtocol;
|
||||
|
||||
// Start the server listening
|
||||
serverTransport_->listen();
|
||||
|
||||
// Run the preServe event to indicate server is now listening
|
||||
// and that it is safe to connect.
|
||||
if (eventHandler_) {
|
||||
eventHandler_->preServe();
|
||||
}
|
||||
|
||||
// Fetch client from server
|
||||
for (;;) {
|
||||
try {
|
||||
// Dereference any resources from any previous client creation
|
||||
// such that a blocking accept does not hold them indefinitely.
|
||||
outputProtocol.reset();
|
||||
inputProtocol.reset();
|
||||
outputTransport.reset();
|
||||
inputTransport.reset();
|
||||
client.reset();
|
||||
|
||||
// If we have reached the limit on the number of concurrent
|
||||
// clients allowed, wait for one or more clients to drain before
|
||||
// accepting another.
|
||||
{
|
||||
Synchronized sync(mon_);
|
||||
while (clients_ >= limit_) {
|
||||
mon_.wait();
|
||||
}
|
||||
}
|
||||
|
||||
client = serverTransport_->accept();
|
||||
|
||||
inputTransport = inputTransportFactory_->getTransport(client);
|
||||
outputTransport = outputTransportFactory_->getTransport(client);
|
||||
if (!outputProtocolFactory_) {
|
||||
inputProtocol = inputProtocolFactory_->getProtocol(inputTransport, outputTransport);
|
||||
outputProtocol = inputProtocol;
|
||||
} else {
|
||||
inputProtocol = inputProtocolFactory_->getProtocol(inputTransport);
|
||||
outputProtocol = outputProtocolFactory_->getProtocol(outputTransport);
|
||||
}
|
||||
|
||||
newlyConnectedClient(shared_ptr<TConnectedClient>(
|
||||
new TConnectedClient(getProcessor(inputProtocol, outputProtocol, client),
|
||||
inputProtocol,
|
||||
outputProtocol,
|
||||
eventHandler_,
|
||||
client),
|
||||
bind(&TServerFramework::disposeConnectedClient, this, _1)));
|
||||
|
||||
} catch (TTransportException& ttx) {
|
||||
releaseOneDescriptor("inputTransport", inputTransport);
|
||||
releaseOneDescriptor("outputTransport", outputTransport);
|
||||
releaseOneDescriptor("client", client);
|
||||
if (ttx.getType() == TTransportException::TIMED_OUT) {
|
||||
// Accept timeout - continue processing.
|
||||
continue;
|
||||
} else if (ttx.getType() == TTransportException::END_OF_FILE
|
||||
|| ttx.getType() == TTransportException::INTERRUPTED) {
|
||||
// Server was interrupted. This only happens when stopping.
|
||||
break;
|
||||
} else {
|
||||
// All other transport exceptions are logged.
|
||||
// State of connection is unknown. Done.
|
||||
string errStr = string("TServerTransport died: ") + ttx.what();
|
||||
GlobalOutput(errStr.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
releaseOneDescriptor("serverTransport", serverTransport_);
|
||||
}
|
||||
|
||||
int64_t TServerFramework::getConcurrentClientLimit() const {
|
||||
Synchronized sync(mon_);
|
||||
return limit_;
|
||||
}
|
||||
|
||||
int64_t TServerFramework::getConcurrentClientCount() const {
|
||||
Synchronized sync(mon_);
|
||||
return clients_;
|
||||
}
|
||||
|
||||
int64_t TServerFramework::getConcurrentClientCountHWM() const {
|
||||
Synchronized sync(mon_);
|
||||
return hwm_;
|
||||
}
|
||||
|
||||
void TServerFramework::setConcurrentClientLimit(int64_t newLimit) {
|
||||
if (newLimit < 1) {
|
||||
throw std::invalid_argument("newLimit must be greater than zero");
|
||||
}
|
||||
Synchronized sync(mon_);
|
||||
limit_ = newLimit;
|
||||
if (limit_ - clients_ > 0) {
|
||||
mon_.notify();
|
||||
}
|
||||
}
|
||||
|
||||
void TServerFramework::stop() {
|
||||
// Order is important because serve() releases serverTransport_ when it is
|
||||
// interrupted, which closes the socket that interruptChildren uses.
|
||||
serverTransport_->interruptChildren();
|
||||
serverTransport_->interrupt();
|
||||
}
|
||||
|
||||
void TServerFramework::newlyConnectedClient(const boost::shared_ptr<TConnectedClient>& pClient) {
|
||||
{
|
||||
Synchronized sync(mon_);
|
||||
++clients_;
|
||||
hwm_ = (std::max)(hwm_, clients_);
|
||||
}
|
||||
|
||||
onClientConnected(pClient);
|
||||
}
|
||||
|
||||
void TServerFramework::disposeConnectedClient(TConnectedClient* pClient) {
|
||||
onClientDisconnected(pClient);
|
||||
delete pClient;
|
||||
|
||||
Synchronized sync(mon_);
|
||||
if (limit_ - --clients_ > 0) {
|
||||
mon_.notify();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} // apache::thrift::server
|
184
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TServerFramework.h
generated
vendored
Normal file
184
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TServerFramework.h
generated
vendored
Normal file
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_SERVER_TSERVERFRAMEWORK_H_
|
||||
#define _THRIFT_SERVER_TSERVERFRAMEWORK_H_ 1
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <stdint.h>
|
||||
#include <thrift/TProcessor.h>
|
||||
#include <thrift/concurrency/Monitor.h>
|
||||
#include <thrift/server/TConnectedClient.h>
|
||||
#include <thrift/server/TServer.h>
|
||||
#include <thrift/transport/TServerTransport.h>
|
||||
#include <thrift/transport/TTransport.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace server {
|
||||
|
||||
/**
|
||||
* TServerFramework provides a single consolidated processing loop for
|
||||
* servers. By having a single processing loop, behavior between servers
|
||||
* is more predictable and maintenance cost is lowered. Implementations
|
||||
* of TServerFramework must provide a method to deal with a client that
|
||||
* connects and one that disconnects.
|
||||
*
|
||||
* While this functionality could be rolled directly into TServer, and
|
||||
* probably should be, it would break the TServer interface contract so
|
||||
* to maintain backwards compatibility for third party servers, no TServers
|
||||
* were harmed in the making of this class.
|
||||
*/
|
||||
class TServerFramework : public TServer {
|
||||
public:
|
||||
TServerFramework(
|
||||
const boost::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
|
||||
const boost::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
|
||||
const boost::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
|
||||
const boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory);
|
||||
|
||||
TServerFramework(
|
||||
const boost::shared_ptr<apache::thrift::TProcessor>& processor,
|
||||
const boost::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
|
||||
const boost::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
|
||||
const boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory);
|
||||
|
||||
TServerFramework(
|
||||
const boost::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
|
||||
const boost::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
|
||||
const boost::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
|
||||
const boost::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
|
||||
const boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
|
||||
const boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory);
|
||||
|
||||
TServerFramework(
|
||||
const boost::shared_ptr<apache::thrift::TProcessor>& processor,
|
||||
const boost::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
|
||||
const boost::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
|
||||
const boost::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
|
||||
const boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
|
||||
const boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory);
|
||||
|
||||
virtual ~TServerFramework();
|
||||
|
||||
/**
|
||||
* Accept clients from the TServerTransport and add them for processing.
|
||||
* Call stop() on another thread to interrupt processing
|
||||
* and return control to the caller.
|
||||
* Post-conditions (return guarantees):
|
||||
* The serverTransport will be closed.
|
||||
*/
|
||||
virtual void serve();
|
||||
|
||||
/**
|
||||
* Interrupt serve() so that it meets post-conditions and returns.
|
||||
*/
|
||||
virtual void stop();
|
||||
|
||||
/**
|
||||
* Get the concurrent client limit.
|
||||
* \returns the concurrent client limit
|
||||
*/
|
||||
virtual int64_t getConcurrentClientLimit() const;
|
||||
|
||||
/**
|
||||
* Get the number of currently connected clients.
|
||||
* \returns the number of currently connected clients
|
||||
*/
|
||||
virtual int64_t getConcurrentClientCount() const;
|
||||
|
||||
/**
|
||||
* Get the highest number of concurrent clients.
|
||||
* \returns the highest number of concurrent clients
|
||||
*/
|
||||
virtual int64_t getConcurrentClientCountHWM() const;
|
||||
|
||||
/**
|
||||
* Set the concurrent client limit. This can be changed while
|
||||
* the server is serving however it will not necessarily be
|
||||
* enforced until the next client is accepted and added. If the
|
||||
* limit is lowered below the number of connected clients, no
|
||||
* action is taken to disconnect the clients.
|
||||
* The default value used if this is not called is INT64_MAX.
|
||||
* \param[in] newLimit the new limit of concurrent clients
|
||||
* \throws std::invalid_argument if newLimit is less than 1
|
||||
*/
|
||||
virtual void setConcurrentClientLimit(int64_t newLimit);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* A client has connected. The implementation is responsible for managing the
|
||||
* lifetime of the client object. This is called during the serve() thread,
|
||||
* therefore a failure to return quickly will result in new client connection
|
||||
* delays.
|
||||
*
|
||||
* \param[in] pClient the newly connected client
|
||||
*/
|
||||
virtual void onClientConnected(const boost::shared_ptr<TConnectedClient>& pClient) = 0;
|
||||
|
||||
/**
|
||||
* A client has disconnected.
|
||||
* When called:
|
||||
* The server no longer tracks the client.
|
||||
* The client TTransport has already been closed.
|
||||
* The implementation must not delete the pointer.
|
||||
*
|
||||
* \param[in] pClient the disconnected client
|
||||
*/
|
||||
virtual void onClientDisconnected(TConnectedClient* pClient) = 0;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Common handling for new connected clients. Implements concurrent
|
||||
* client rate limiting after onClientConnected returns by blocking the
|
||||
* serve() thread if the limit has been reached.
|
||||
*/
|
||||
void newlyConnectedClient(const boost::shared_ptr<TConnectedClient>& pClient);
|
||||
|
||||
/**
|
||||
* Smart pointer client deletion.
|
||||
* Calls onClientDisconnected and then deletes pClient.
|
||||
*/
|
||||
void disposeConnectedClient(TConnectedClient* pClient);
|
||||
|
||||
/**
|
||||
* Monitor for limiting the number of concurrent clients.
|
||||
*/
|
||||
apache::thrift::concurrency::Monitor mon_;
|
||||
|
||||
/**
|
||||
* The number of concurrent clients.
|
||||
*/
|
||||
int64_t clients_;
|
||||
|
||||
/**
|
||||
* The high water mark of concurrent clients.
|
||||
*/
|
||||
int64_t hwm_;
|
||||
|
||||
/**
|
||||
* The limit on the number of concurrent clients.
|
||||
*/
|
||||
int64_t limit_;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::server
|
||||
|
||||
#endif // #ifndef _THRIFT_SERVER_TSERVERFRAMEWORK_H_
|
107
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TSimpleServer.cpp
generated
vendored
Normal file
107
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TSimpleServer.cpp
generated
vendored
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/server/TSimpleServer.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace server {
|
||||
|
||||
using apache::thrift::protocol::TProtocol;
|
||||
using apache::thrift::protocol::TProtocolFactory;
|
||||
using apache::thrift::transport::TServerTransport;
|
||||
using apache::thrift::transport::TTransport;
|
||||
using apache::thrift::transport::TTransportException;
|
||||
using apache::thrift::transport::TTransportFactory;
|
||||
using boost::shared_ptr;
|
||||
using std::string;
|
||||
|
||||
TSimpleServer::TSimpleServer(const shared_ptr<TProcessorFactory>& processorFactory,
|
||||
const shared_ptr<TServerTransport>& serverTransport,
|
||||
const shared_ptr<TTransportFactory>& transportFactory,
|
||||
const shared_ptr<TProtocolFactory>& protocolFactory)
|
||||
: TServerFramework(processorFactory, serverTransport, transportFactory, protocolFactory) {
|
||||
TServerFramework::setConcurrentClientLimit(1);
|
||||
}
|
||||
|
||||
TSimpleServer::TSimpleServer(const shared_ptr<TProcessor>& processor,
|
||||
const shared_ptr<TServerTransport>& serverTransport,
|
||||
const shared_ptr<TTransportFactory>& transportFactory,
|
||||
const shared_ptr<TProtocolFactory>& protocolFactory)
|
||||
: TServerFramework(processor, serverTransport, transportFactory, protocolFactory) {
|
||||
TServerFramework::setConcurrentClientLimit(1);
|
||||
}
|
||||
|
||||
TSimpleServer::TSimpleServer(const shared_ptr<TProcessorFactory>& processorFactory,
|
||||
const shared_ptr<TServerTransport>& serverTransport,
|
||||
const shared_ptr<TTransportFactory>& inputTransportFactory,
|
||||
const shared_ptr<TTransportFactory>& outputTransportFactory,
|
||||
const shared_ptr<TProtocolFactory>& inputProtocolFactory,
|
||||
const shared_ptr<TProtocolFactory>& outputProtocolFactory)
|
||||
: TServerFramework(processorFactory,
|
||||
serverTransport,
|
||||
inputTransportFactory,
|
||||
outputTransportFactory,
|
||||
inputProtocolFactory,
|
||||
outputProtocolFactory) {
|
||||
TServerFramework::setConcurrentClientLimit(1);
|
||||
}
|
||||
|
||||
TSimpleServer::TSimpleServer(const shared_ptr<TProcessor>& processor,
|
||||
const shared_ptr<TServerTransport>& serverTransport,
|
||||
const shared_ptr<TTransportFactory>& inputTransportFactory,
|
||||
const shared_ptr<TTransportFactory>& outputTransportFactory,
|
||||
const shared_ptr<TProtocolFactory>& inputProtocolFactory,
|
||||
const shared_ptr<TProtocolFactory>& outputProtocolFactory)
|
||||
: TServerFramework(processor,
|
||||
serverTransport,
|
||||
inputTransportFactory,
|
||||
outputTransportFactory,
|
||||
inputProtocolFactory,
|
||||
outputProtocolFactory) {
|
||||
TServerFramework::setConcurrentClientLimit(1);
|
||||
}
|
||||
|
||||
TSimpleServer::~TSimpleServer() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The main body of customized implementation for TSimpleServer is quite simple:
|
||||
* When a client connects, use the serve() thread to drive it to completion thus
|
||||
* blocking new connections.
|
||||
*/
|
||||
void TSimpleServer::onClientConnected(const shared_ptr<TConnectedClient>& pClient) {
|
||||
pClient->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* TSimpleServer does not track clients so there is nothing to do here.
|
||||
*/
|
||||
void TSimpleServer::onClientDisconnected(TConnectedClient*) {
|
||||
}
|
||||
|
||||
/**
|
||||
* This makes little sense to the simple server because it is not capable
|
||||
* of having more than one client at a time, so we hide it.
|
||||
*/
|
||||
void TSimpleServer::setConcurrentClientLimit(int64_t) {
|
||||
}
|
||||
}
|
||||
}
|
||||
} // apache::thrift::server
|
77
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TSimpleServer.h
generated
vendored
Normal file
77
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TSimpleServer.h
generated
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_SERVER_TSIMPLESERVER_H_
|
||||
#define _THRIFT_SERVER_TSIMPLESERVER_H_ 1
|
||||
|
||||
#include <thrift/server/TServerFramework.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace server {
|
||||
|
||||
/**
|
||||
* This is the most basic simple server. It is single-threaded and runs a
|
||||
* continuous loop of accepting a single connection, processing requests on
|
||||
* that connection until it closes, and then repeating.
|
||||
*/
|
||||
class TSimpleServer : public TServerFramework {
|
||||
public:
|
||||
TSimpleServer(
|
||||
const boost::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
|
||||
const boost::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
|
||||
const boost::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
|
||||
const boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory);
|
||||
|
||||
TSimpleServer(
|
||||
const boost::shared_ptr<apache::thrift::TProcessor>& processor,
|
||||
const boost::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
|
||||
const boost::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
|
||||
const boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory);
|
||||
|
||||
TSimpleServer(
|
||||
const boost::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
|
||||
const boost::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
|
||||
const boost::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
|
||||
const boost::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
|
||||
const boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
|
||||
const boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory);
|
||||
|
||||
TSimpleServer(
|
||||
const boost::shared_ptr<apache::thrift::TProcessor>& processor,
|
||||
const boost::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
|
||||
const boost::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
|
||||
const boost::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
|
||||
const boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
|
||||
const boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory);
|
||||
|
||||
virtual ~TSimpleServer();
|
||||
|
||||
protected:
|
||||
virtual void onClientConnected(const boost::shared_ptr<TConnectedClient>& pClient) /* override */;
|
||||
virtual void onClientDisconnected(TConnectedClient* pClient) /* override */;
|
||||
|
||||
private:
|
||||
void setConcurrentClientLimit(int64_t newLimit); // hide
|
||||
};
|
||||
}
|
||||
}
|
||||
} // apache::thrift::server
|
||||
|
||||
#endif // #ifndef _THRIFT_SERVER_TSIMPLESERVER_H_
|
132
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TThreadPoolServer.cpp
generated
vendored
Normal file
132
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TThreadPoolServer.cpp
generated
vendored
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <thrift/server/TThreadPoolServer.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace server {
|
||||
|
||||
using apache::thrift::concurrency::ThreadManager;
|
||||
using apache::thrift::protocol::TProtocol;
|
||||
using apache::thrift::protocol::TProtocolFactory;
|
||||
using apache::thrift::transport::TServerTransport;
|
||||
using apache::thrift::transport::TTransport;
|
||||
using apache::thrift::transport::TTransportException;
|
||||
using apache::thrift::transport::TTransportFactory;
|
||||
using boost::shared_ptr;
|
||||
using std::string;
|
||||
|
||||
TThreadPoolServer::TThreadPoolServer(const shared_ptr<TProcessorFactory>& processorFactory,
|
||||
const shared_ptr<TServerTransport>& serverTransport,
|
||||
const shared_ptr<TTransportFactory>& transportFactory,
|
||||
const shared_ptr<TProtocolFactory>& protocolFactory,
|
||||
const shared_ptr<ThreadManager>& threadManager)
|
||||
: TServerFramework(processorFactory, serverTransport, transportFactory, protocolFactory),
|
||||
threadManager_(threadManager),
|
||||
timeout_(0),
|
||||
taskExpiration_(0) {
|
||||
}
|
||||
|
||||
TThreadPoolServer::TThreadPoolServer(const shared_ptr<TProcessor>& processor,
|
||||
const shared_ptr<TServerTransport>& serverTransport,
|
||||
const shared_ptr<TTransportFactory>& transportFactory,
|
||||
const shared_ptr<TProtocolFactory>& protocolFactory,
|
||||
const shared_ptr<ThreadManager>& threadManager)
|
||||
: TServerFramework(processor, serverTransport, transportFactory, protocolFactory),
|
||||
threadManager_(threadManager),
|
||||
timeout_(0),
|
||||
taskExpiration_(0) {
|
||||
}
|
||||
|
||||
TThreadPoolServer::TThreadPoolServer(const shared_ptr<TProcessorFactory>& processorFactory,
|
||||
const shared_ptr<TServerTransport>& serverTransport,
|
||||
const shared_ptr<TTransportFactory>& inputTransportFactory,
|
||||
const shared_ptr<TTransportFactory>& outputTransportFactory,
|
||||
const shared_ptr<TProtocolFactory>& inputProtocolFactory,
|
||||
const shared_ptr<TProtocolFactory>& outputProtocolFactory,
|
||||
const shared_ptr<ThreadManager>& threadManager)
|
||||
: TServerFramework(processorFactory,
|
||||
serverTransport,
|
||||
inputTransportFactory,
|
||||
outputTransportFactory,
|
||||
inputProtocolFactory,
|
||||
outputProtocolFactory),
|
||||
threadManager_(threadManager),
|
||||
timeout_(0),
|
||||
taskExpiration_(0) {
|
||||
}
|
||||
|
||||
TThreadPoolServer::TThreadPoolServer(const shared_ptr<TProcessor>& processor,
|
||||
const shared_ptr<TServerTransport>& serverTransport,
|
||||
const shared_ptr<TTransportFactory>& inputTransportFactory,
|
||||
const shared_ptr<TTransportFactory>& outputTransportFactory,
|
||||
const shared_ptr<TProtocolFactory>& inputProtocolFactory,
|
||||
const shared_ptr<TProtocolFactory>& outputProtocolFactory,
|
||||
const shared_ptr<ThreadManager>& threadManager)
|
||||
: TServerFramework(processor,
|
||||
serverTransport,
|
||||
inputTransportFactory,
|
||||
outputTransportFactory,
|
||||
inputProtocolFactory,
|
||||
outputProtocolFactory),
|
||||
threadManager_(threadManager),
|
||||
timeout_(0),
|
||||
taskExpiration_(0) {
|
||||
}
|
||||
|
||||
TThreadPoolServer::~TThreadPoolServer() {
|
||||
}
|
||||
|
||||
void TThreadPoolServer::serve() {
|
||||
TServerFramework::serve();
|
||||
threadManager_->stop();
|
||||
}
|
||||
|
||||
int64_t TThreadPoolServer::getTimeout() const {
|
||||
return timeout_;
|
||||
}
|
||||
|
||||
void TThreadPoolServer::setTimeout(int64_t value) {
|
||||
timeout_ = value;
|
||||
}
|
||||
|
||||
int64_t TThreadPoolServer::getTaskExpiration() const {
|
||||
return taskExpiration_;
|
||||
}
|
||||
|
||||
void TThreadPoolServer::setTaskExpiration(int64_t value) {
|
||||
taskExpiration_ = value;
|
||||
}
|
||||
|
||||
boost::shared_ptr<apache::thrift::concurrency::ThreadManager>
|
||||
TThreadPoolServer::getThreadManager() const {
|
||||
return threadManager_;
|
||||
}
|
||||
|
||||
void TThreadPoolServer::onClientConnected(const shared_ptr<TConnectedClient>& pClient) {
|
||||
threadManager_->add(pClient, getTimeout(), getTaskExpiration());
|
||||
}
|
||||
|
||||
void TThreadPoolServer::onClientDisconnected(TConnectedClient*) {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} // apache::thrift::server
|
101
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TThreadPoolServer.h
generated
vendored
Normal file
101
vendor/git.apache.org/thrift.git/lib/cpp/src/thrift/server/TThreadPoolServer.h
generated
vendored
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _THRIFT_SERVER_TTHREADPOOLSERVER_H_
|
||||
#define _THRIFT_SERVER_TTHREADPOOLSERVER_H_ 1
|
||||
|
||||
#include <boost/atomic.hpp>
|
||||
#include <thrift/concurrency/ThreadManager.h>
|
||||
#include <thrift/server/TServerFramework.h>
|
||||
|
||||
namespace apache {
|
||||
namespace thrift {
|
||||
namespace server {
|
||||
|
||||
/**
|
||||
* Manage clients using a thread pool.
|
||||
*/
|
||||
class TThreadPoolServer : public TServerFramework {
|
||||
public:
|
||||
TThreadPoolServer(
|
||||
const boost::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
|
||||
const boost::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
|
||||
const boost::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
|
||||
const boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory,
|
||||
const boost::shared_ptr<apache::thrift::concurrency::ThreadManager>& threadManager
|
||||
= apache::thrift::concurrency::ThreadManager::newSimpleThreadManager());
|
||||
|
||||
TThreadPoolServer(
|
||||
const boost::shared_ptr<apache::thrift::TProcessor>& processor,
|
||||
const boost::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
|
||||
const boost::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
|
||||
const boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory,
|
||||
const boost::shared_ptr<apache::thrift::concurrency::ThreadManager>& threadManager
|
||||
= apache::thrift::concurrency::ThreadManager::newSimpleThreadManager());
|
||||
|
||||
TThreadPoolServer(
|
||||
const boost::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
|
||||
const boost::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
|
||||
const boost::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
|
||||
const boost::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
|
||||
const boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
|
||||
const boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory,
|
||||
const boost::shared_ptr<apache::thrift::concurrency::ThreadManager>& threadManager
|
||||
= apache::thrift::concurrency::ThreadManager::newSimpleThreadManager());
|
||||
|
||||
TThreadPoolServer(
|
||||
const boost::shared_ptr<apache::thrift::TProcessor>& processor,
|
||||
const boost::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
|
||||
const boost::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
|
||||
const boost::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
|
||||
const boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
|
||||
const boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory,
|
||||
const boost::shared_ptr<apache::thrift::concurrency::ThreadManager>& threadManager
|
||||
= apache::thrift::concurrency::ThreadManager::newSimpleThreadManager());
|
||||
|
||||
virtual ~TThreadPoolServer();
|
||||
|
||||
/**
|
||||
* Post-conditions (return guarantees):
|
||||
* There will be no clients connected.
|
||||
*/
|
||||
virtual void serve();
|
||||
|
||||
virtual int64_t getTimeout() const;
|
||||
virtual void setTimeout(int64_t value);
|
||||
|
||||
virtual int64_t getTaskExpiration() const;
|
||||
virtual void setTaskExpiration(int64_t value);
|
||||
|
||||
virtual boost::shared_ptr<apache::thrift::concurrency::ThreadManager> getThreadManager() const;
|
||||
|
||||
protected:
|
||||
virtual void onClientConnected(const boost::shared_ptr<TConnectedClient>& pClient) /* override */;
|
||||
virtual void onClientDisconnected(TConnectedClient* pClient) /* override */;
|
||||
|
||||
boost::shared_ptr<apache::thrift::concurrency::ThreadManager> threadManager_;
|
||||
boost::atomic<int64_t> timeout_;
|
||||
boost::atomic<int64_t> taskExpiration_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
} // apache::thrift::server
|
||||
|
||||
#endif // #ifndef _THRIFT_SERVER_TTHREADPOOLSERVER_H_
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue