Upgrading dependency to Thrift 0.12.0

This commit is contained in:
Renan DelValle 2018-11-27 18:03:50 -08:00
parent 3e4590dcc0
commit 356978cb42
No known key found for this signature in database
GPG key ID: C240AD6D6F443EC9
1302 changed files with 101701 additions and 26784 deletions

View file

@ -28,6 +28,7 @@ set( thriftcpp_SOURCES
src/thrift/TApplicationException.cpp
src/thrift/TOutput.cpp
src/thrift/async/TAsyncChannel.cpp
src/thrift/async/TAsyncProtocolProcessor.cpp
src/thrift/async/TConcurrentClientSyncInfo.h
src/thrift/async/TConcurrentClientSyncInfo.cpp
src/thrift/concurrency/ThreadManager.cpp
@ -57,7 +58,7 @@ set( thriftcpp_SOURCES
src/thrift/server/TThreadedServer.cpp
)
# This files don't work on Windows CE as there is no pipe support
# These 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
@ -138,7 +139,8 @@ endif()
# Thrift non blocking server
set( thriftcppnb_SOURCES
src/thrift/server/TNonblockingServer.cpp
src/thrift/async/TAsyncProtocolProcessor.cpp
src/thrift/transport/TNonblockingServerSocket.cpp
src/thrift/transport/TNonblockingSSLServerSocket.cpp
src/thrift/async/TEvhttpServer.cpp
src/thrift/async/TEvhttpClientChannel.cpp
)

View file

@ -62,7 +62,7 @@ pkgconfig_DATA += thrift-qt5.pc
endif
AM_CXXFLAGS = -Wall -Wextra -pedantic
AM_CPPFLAGS = $(BOOST_CPPFLAGS) $(OPENSSL_INCLUDES) -I$(srcdir)/src -D__STDC_LIMIT_MACROS
AM_CPPFLAGS = $(BOOST_CPPFLAGS) $(OPENSSL_INCLUDES) -I$(srcdir)/src -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
# Define the source files for the module
@ -70,6 +70,7 @@ libthrift_la_SOURCES = src/thrift/TApplicationException.cpp \
src/thrift/TOutput.cpp \
src/thrift/VirtualProfiling.cpp \
src/thrift/async/TAsyncChannel.cpp \
src/thrift/async/TAsyncProtocolProcessor.cpp \
src/thrift/async/TConcurrentClientSyncInfo.cpp \
src/thrift/concurrency/ThreadManager.cpp \
src/thrift/concurrency/TimerManager.cpp \
@ -94,6 +95,8 @@ libthrift_la_SOURCES = src/thrift/TApplicationException.cpp \
src/thrift/transport/TSocketPool.cpp \
src/thrift/transport/TServerSocket.cpp \
src/thrift/transport/TSSLServerSocket.cpp \
src/thrift/transport/TNonblockingServerSocket.cpp \
src/thrift/transport/TNonblockingSSLServerSocket.cpp \
src/thrift/transport/TTransportUtils.cpp \
src/thrift/transport/TBufferTransports.cpp \
src/thrift/server/TConnectedClient.cpp \
@ -114,13 +117,12 @@ libthrift_la_SOURCES += src/thrift/concurrency/Mutex.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
src/thrift/protocol/THeaderProtocol.cpp
libthriftqt_la_MOC = src/thrift/qt/moc_TQTcpServer.cpp
@ -148,7 +150,7 @@ 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)
libthriftz_la_LDFLAGS = -release $(VERSION) $(BOOST_LDFLAGS) $(ZLIB_LIBS)
libthriftqt_la_LDFLAGS = -release $(VERSION) $(BOOST_LDFLAGS) $(QT_LIBS)
libthriftqt5_la_LDFLAGS = -release $(VERSION) $(BOOST_LDFLAGS) $(QT5_LIBS)
@ -162,8 +164,8 @@ include_thrift_HEADERS = \
src/thrift/TProcessor.h \
src/thrift/TApplicationException.h \
src/thrift/TLogging.h \
src/thrift/cxxfunctional.h \
src/thrift/TToString.h \
src/thrift/stdcxx.h \
src/thrift/TBase.h
include_concurrencydir = $(include_thriftdir)/concurrency
@ -212,6 +214,9 @@ include_transport_HEADERS = \
src/thrift/transport/TServerSocket.h \
src/thrift/transport/TSSLServerSocket.h \
src/thrift/transport/TServerTransport.h \
src/thrift/transport/TNonblockingServerTransport.h \
src/thrift/transport/TNonblockingServerSocket.h \
src/thrift/transport/TNonblockingSSLServerSocket.h \
src/thrift/transport/THttpTransport.h \
src/thrift/transport/THttpClient.h \
src/thrift/transport/THttpServer.h \
@ -260,8 +265,6 @@ 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 \

View file

@ -19,7 +19,6 @@ 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
@ -55,15 +54,22 @@ you are using libthriftnb you will also need libevent.
## Dependencies
boost shared pointers
http://www.boost.org/libs/smart_ptr/smart_ptr.htm
If your C++ environment implements C++11 or later, thrift will automatically use
std::shared_ptr. Otherwise you will need the boost library to provide a shared_ptr
implementation for C++ environments pre-C++11. If you are linking against code
that expects to be using boost::shared_ptr, you can define the preprocessor
variable FORCE_BOOST_SMART_PTR for your build of thrift to make it use boost instead
of std for a number of memory related classes. See thrift/stdcxx.h for more.
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:
Both the autoconf and cmake build systems are able to automatically detect many
system configurations without the need to specify library locations, however if
you run into problems or want to redirect thrift to build and link against your
own provided third party libraries:
BOOST_ROOT : For boost, e.g. D:\boost_1_55_0
OPENSSL_ROOT_DIR : For OpenSSL, e.g. D:\OpenSSL-Win32
@ -74,13 +80,7 @@ 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.
The same linking guidelines described above for libthriftnb apply to windows as well.
## Linking Against Thrift
@ -93,8 +93,7 @@ the config header: "windows/confg.h"
## Dependencies
boost shared pointers
http://www.boost.org/libs/smart_ptr/smart_ptr.htm
The same dependencies for shared_ptr as described above apply to windows as well.
boost thread
http://www.boost.org/doc/libs/release/doc/html/thread.html
@ -272,3 +271,26 @@ 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.
# Breaking Changes
## 0.11.0
Older versions of thrift depended on the <boost/smart_ptr.hpp> classes which
were used in thrift headers to define interfaces. Thrift now detects C++11
at build time and will prefer to use <memory> classes from C++11 instead.
You can force the library to build with boost memory classes by defining the
preprocessor macro `FORCE_BOOST_SMART_PTR`. (THRIFT-2221)
In the pthread mutex implementation, the contention profiling code was enabled
by default in all builds. This changed to be disabled by default. (THRIFT-4151)
In older releases, if a TSSLSocketFactory's lifetime was not at least as long
as the TSSLSockets it created, we silently reverted openssl to unsafe multithread behavior
and so the results were undefined. Changes were made in 0.11.0 that cause either an
assertion or a core instead of undefined behavior. The lifetime of a TSSLSocketFactory
*must* be longer than any TSSLSocket that it creates, otherwise openssl will be cleaned
up too early. If the static boolean is set to disable openssl initialization and
cleanup and leave it up to the consuming application, this requirement is not needed.
(THRIFT-4164)

View file

@ -53,6 +53,12 @@
<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\server\TConnectedClient.cpp"/>
<ClCompile Include="src\thrift\server\TNonblockingServer.cpp"/>
<ClCompile Include="src\thrift\server\TServerFramework.cpp"/>
<ClCompile Include="src\thrift\server\TSimpleServer.cpp"/>
<ClCompile Include="src\thrift\server\TThreadedServer.cpp"/>
<ClCompile Include="src\thrift\server\TThreadPoolServer.cpp"/>
<ClCompile Include="src\thrift\TApplicationException.cpp"/>
<ClCompile Include="src\thrift\TOutput.cpp"/>
<ClCompile Include="src\thrift\transport\TBufferTransports.cpp"/>

View file

@ -35,16 +35,21 @@
</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"/>
<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" />
<ClCompile Include="src\thrift\transport\TNonblockingServerSocket.cpp" />
<ClCompile Include="src\thrift\transport\TNonblockingSSLServerSocket.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\transport\TNonblockingServerSocket.h" />
<ClInclude Include="src\thrift\transport\TNonblockingServerTransport.h" />
<ClInclude Include="src\thrift\transport\TNonblockingSSLServerSocket.h" />
<ClInclude Include="src\thrift\windows\config.h" />
<ClInclude Include="src\thrift\windows\force_inc.h" />
<ClInclude Include="src\thrift\windows\TargetVersion.h" />
@ -290,4 +295,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View file

@ -10,6 +10,9 @@
<Filter Include="windows">
<UniqueIdentifier>{60fc9e5e-0866-4aba-8662-439bb4a461d3}</UniqueIdentifier>
</Filter>
<Filter Include="transport">
<UniqueIdentifier>{23fe2fde-a7c9-43ec-a409-7f53df5eee64}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\thrift\server\TNonblockingServer.cpp">
@ -27,6 +30,12 @@
<ClCompile Include="src\thrift\windows\StdAfx.cpp">
<Filter>windows</Filter>
</ClCompile>
<ClCompile Include="src\thrift\transport\TNonblockingServerSocket.cpp">
<Filter>transport</Filter>
</ClCompile>
<ClCompile Include="src\thrift\transport\TNonblockingSSLServerSocket.cpp">
<Filter>transport</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\thrift\server\TNonblockingServer.h">
@ -53,5 +62,14 @@
<ClInclude Include="src\thrift\windows\force_inc.h">
<Filter>windows</Filter>
</ClInclude>
<ClInclude Include="src\thrift\transport\TNonblockingServerSocket.h">
<Filter>transport</Filter>
</ClInclude>
<ClInclude Include="src\thrift\transport\TNonblockingServerTransport.h">
<Filter>transport</Filter>
</ClInclude>
<ClInclude Include="src\thrift\transport\TNonblockingSSLServerSocket.h">
<Filter>transport</Filter>
</ClInclude>
</ItemGroup>
</Project>
</Project>

View file

@ -33,8 +33,8 @@ namespace thrift {
template <class Protocol_>
class TDispatchProcessorT : public TProcessor {
public:
virtual bool process(boost::shared_ptr<protocol::TProtocol> in,
boost::shared_ptr<protocol::TProtocol> out,
virtual bool process(stdcxx::shared_ptr<protocol::TProtocol> in,
stdcxx::shared_ptr<protocol::TProtocol> out,
void* connectionContext) {
protocol::TProtocol* inRaw = in.get();
protocol::TProtocol* outRaw = out.get();
@ -105,8 +105,8 @@ protected:
*/
class TDispatchProcessor : public TProcessor {
public:
virtual bool process(boost::shared_ptr<protocol::TProtocol> in,
boost::shared_ptr<protocol::TProtocol> out,
virtual bool process(stdcxx::shared_ptr<protocol::TProtocol> in,
stdcxx::shared_ptr<protocol::TProtocol> out,
void* connectionContext) {
std::string fname;
protocol::TMessageType mtype;

View file

@ -18,9 +18,9 @@
*/
#include <thrift/Thrift.h>
#include <thrift/TToString.h>
#include <cstring>
#include <cstdlib>
#include <boost/lexical_cast.hpp>
#include <stdarg.h>
#include <stdio.h>
@ -94,13 +94,13 @@ void TOutput::errorTimeWrapper(const char* msg) {
}
void TOutput::perror(const char* message, int errno_copy) {
std::string out = message + strerror_s(errno_copy);
std::string out = message + std::string(": ") + 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);
return "errno = " + to_string(errno_copy);
#else // HAVE_STRERROR_R
char b_errbuf[1024] = {'\0'};
@ -112,7 +112,7 @@ std::string TOutput::strerror_s(int errno_copy) {
if (rv == -1) {
// strerror_r failed. omgwtfbbq.
return "XSI-compliant strerror_r() failed with errno = "
+ boost::lexical_cast<std::string>(errno_copy);
+ to_string(errno_copy);
}
#endif
// Can anyone prove that explicit cast is probably not necessary

View file

@ -22,7 +22,7 @@
#include <string>
#include <thrift/protocol/TProtocol.h>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
@ -142,28 +142,28 @@ class TProcessor {
public:
virtual ~TProcessor() {}
virtual bool process(boost::shared_ptr<protocol::TProtocol> in,
boost::shared_ptr<protocol::TProtocol> out,
virtual bool process(stdcxx::shared_ptr<protocol::TProtocol> in,
stdcxx::shared_ptr<protocol::TProtocol> out,
void* connectionContext) = 0;
bool process(boost::shared_ptr<apache::thrift::protocol::TProtocol> io, void* connectionContext) {
bool process(stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> io, void* connectionContext) {
return process(io, io, connectionContext);
}
boost::shared_ptr<TProcessorEventHandler> getEventHandler() const { return eventHandler_; }
stdcxx::shared_ptr<TProcessorEventHandler> getEventHandler() const { return eventHandler_; }
void setEventHandler(boost::shared_ptr<TProcessorEventHandler> eventHandler) {
void setEventHandler(stdcxx::shared_ptr<TProcessorEventHandler> eventHandler) {
eventHandler_ = eventHandler;
}
protected:
TProcessor() {}
boost::shared_ptr<TProcessorEventHandler> eventHandler_;
stdcxx::shared_ptr<TProcessorEventHandler> eventHandler_;
};
/**
* This is a helper class to allow boost::shared_ptr to be used with handler
* This is a helper class to allow stdcxx::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
@ -177,7 +177,7 @@ protected:
template <typename HandlerFactory_>
class ReleaseHandler {
public:
ReleaseHandler(const boost::shared_ptr<HandlerFactory_>& handlerFactory)
ReleaseHandler(const stdcxx::shared_ptr<HandlerFactory_>& handlerFactory)
: handlerFactory_(handlerFactory) {}
void operator()(typename HandlerFactory_::Handler* handler) {
@ -187,18 +187,18 @@ public:
}
private:
boost::shared_ptr<HandlerFactory_> handlerFactory_;
stdcxx::shared_ptr<HandlerFactory_> handlerFactory_;
};
struct TConnectionInfo {
// The input and output protocols
boost::shared_ptr<protocol::TProtocol> input;
boost::shared_ptr<protocol::TProtocol> output;
stdcxx::shared_ptr<protocol::TProtocol> input;
stdcxx::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;
stdcxx::shared_ptr<transport::TTransport> transport;
};
class TProcessorFactory {
@ -212,17 +212,17 @@ public:
* 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;
virtual stdcxx::shared_ptr<TProcessor> getProcessor(const TConnectionInfo& connInfo) = 0;
};
class TSingletonProcessorFactory : public TProcessorFactory {
public:
TSingletonProcessorFactory(boost::shared_ptr<TProcessor> processor) : processor_(processor) {}
TSingletonProcessorFactory(stdcxx::shared_ptr<TProcessor> processor) : processor_(processor) {}
boost::shared_ptr<TProcessor> getProcessor(const TConnectionInfo&) { return processor_; }
stdcxx::shared_ptr<TProcessor> getProcessor(const TConnectionInfo&) { return processor_; }
private:
boost::shared_ptr<TProcessor> processor_;
stdcxx::shared_ptr<TProcessor> processor_;
};
}
} // apache::thrift

View file

@ -20,20 +20,45 @@
#ifndef _THRIFT_TOSTRING_H_
#define _THRIFT_TOSTRING_H_ 1
#include <boost/lexical_cast.hpp>
#include <vector>
#include <cmath>
#include <limits>
#include <map>
#include <set>
#include <string>
#include <sstream>
#include <string>
#include <vector>
namespace apache {
namespace thrift {
template <typename T>
std::string to_string(const T& t) {
return boost::lexical_cast<std::string>(t);
std::ostringstream o;
o << t;
return o.str();
}
// TODO: replace the computations below with std::numeric_limits::max_digits10 once C++11
// is enabled.
inline std::string to_string(const float& t) {
std::ostringstream o;
o.precision(static_cast<std::streamsize>(std::ceil(static_cast<double>(std::numeric_limits<float>::digits * std::log10(2.0f) + 1))));
o << t;
return o.str();
}
inline std::string to_string(const double& t) {
std::ostringstream o;
o.precision(static_cast<std::streamsize>(std::ceil(static_cast<double>(std::numeric_limits<double>::digits * std::log10(2.0f) + 1))));
o << t;
return o.str();
}
inline std::string to_string(const long double& t) {
std::ostringstream o;
o.precision(static_cast<std::streamsize>(std::ceil(static_cast<double>(std::numeric_limits<long double>::digits * std::log10(2.0f) + 1))));
o << t;
return o.str();
}
template <typename K, typename V>

View file

@ -20,9 +20,7 @@
#ifndef _THRIFT_TASYNC_BUFFER_PROCESSOR_H_
#define _THRIFT_TASYNC_BUFFER_PROCESSOR_H_ 1
#include <thrift/cxxfunctional.h>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
#include <thrift/transport/TBufferTransports.h>
namespace apache {
@ -36,9 +34,9 @@ public:
// 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 void process(stdcxx::function<void(bool healthy)> _return,
stdcxx::shared_ptr<transport::TBufferBase> ibuf,
stdcxx::shared_ptr<transport::TBufferBase> obuf) = 0;
virtual ~TAsyncBufferProcessor() {}
};
}

View file

@ -18,7 +18,7 @@
*/
#include <thrift/async/TAsyncChannel.h>
#include <thrift/cxxfunctional.h>
#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {

View file

@ -20,7 +20,7 @@
#ifndef _THRIFT_ASYNC_TASYNCCHANNEL_H_
#define _THRIFT_ASYNC_TASYNCCHANNEL_H_ 1
#include <thrift/cxxfunctional.h>
#include <thrift/stdcxx.h>
#include <thrift/Thrift.h>
namespace apache {

View file

@ -35,8 +35,8 @@ 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) {
stdcxx::shared_ptr<protocol::TProtocol> in,
stdcxx::shared_ptr<protocol::TProtocol> out) {
protocol::TProtocol* inRaw = in.get();
protocol::TProtocol* outRaw = out.get();
@ -107,8 +107,8 @@ public:
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) {
stdcxx::shared_ptr<protocol::TProtocol> in,
stdcxx::shared_ptr<protocol::TProtocol> out) {
protocol::TProtocol* inRaw = in.get();
protocol::TProtocol* outRaw = out.get();

View file

@ -20,9 +20,8 @@
#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/stdcxx.h>
#include <thrift/TProcessor.h>
namespace apache {
@ -38,25 +37,25 @@ 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;
virtual void process(stdcxx::function<void(bool success)> _return,
stdcxx::shared_ptr<protocol::TProtocol> in,
stdcxx::shared_ptr<protocol::TProtocol> out) = 0;
void process(apache::thrift::stdcxx::function<void(bool success)> _return,
boost::shared_ptr<apache::thrift::protocol::TProtocol> io) {
void process(stdcxx::function<void(bool success)> _return,
stdcxx::shared_ptr<protocol::TProtocol> io) {
return process(_return, io, io);
}
boost::shared_ptr<TProcessorEventHandler> getEventHandler() const { return eventHandler_; }
stdcxx::shared_ptr<TProcessorEventHandler> getEventHandler() const { return eventHandler_; }
void setEventHandler(boost::shared_ptr<TProcessorEventHandler> eventHandler) {
void setEventHandler(stdcxx::shared_ptr<TProcessorEventHandler> eventHandler) {
eventHandler_ = eventHandler;
}
protected:
TAsyncProcessor() {}
boost::shared_ptr<TProcessorEventHandler> eventHandler_;
stdcxx::shared_ptr<TProcessorEventHandler> eventHandler_;
};
class TAsyncProcessorFactory {
@ -70,16 +69,15 @@ public:
* 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;
virtual stdcxx::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;
using apache::thrift::async::TAsyncProcessor;
}
}

View file

@ -27,10 +27,10 @@ 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));
stdcxx::shared_ptr<TBufferBase> ibuf,
stdcxx::shared_ptr<TBufferBase> obuf) {
stdcxx::shared_ptr<TProtocol> iprot(pfact_->getProtocol(ibuf));
stdcxx::shared_ptr<TProtocol> oprot(pfact_->getProtocol(obuf));
return underlying_
->process(apache::thrift::stdcxx::bind(&TAsyncProtocolProcessor::finish,
_return,
@ -42,7 +42,7 @@ void TAsyncProtocolProcessor::process(apache::thrift::stdcxx::function<void(bool
/* static */ void TAsyncProtocolProcessor::finish(
apache::thrift::stdcxx::function<void(bool healthy)> _return,
boost::shared_ptr<TProtocol> oprot,
stdcxx::shared_ptr<TProtocol> oprot,
bool healthy) {
(void)oprot;
// This is a stub function to hold a reference to oprot.

View file

@ -30,23 +30,23 @@ namespace async {
class TAsyncProtocolProcessor : public TAsyncBufferProcessor {
public:
TAsyncProtocolProcessor(boost::shared_ptr<TAsyncProcessor> underlying,
boost::shared_ptr<apache::thrift::protocol::TProtocolFactory> pfact)
TAsyncProtocolProcessor(stdcxx::shared_ptr<TAsyncProcessor> underlying,
stdcxx::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);
stdcxx::shared_ptr<apache::thrift::transport::TBufferBase> ibuf,
stdcxx::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,
stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> oprot,
bool healthy);
boost::shared_ptr<TAsyncProcessor> underlying_;
boost::shared_ptr<apache::thrift::protocol::TProtocolFactory> pfact_;
stdcxx::shared_ptr<TAsyncProcessor> underlying_;
stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory> pfact_;
};
}
}

View file

@ -22,7 +22,7 @@
#include <thrift/protocol/TProtocol.h>
#include <thrift/concurrency/Mutex.h>
#include <thrift/concurrency/Monitor.h>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
#include <vector>
#include <string>
#include <map>
@ -60,7 +60,7 @@ private:
class TConcurrentClientSyncInfo {
private: // typedefs
typedef boost::shared_ptr< ::apache::thrift::concurrency::Monitor> MonitorPtr;
typedef stdcxx::shared_ptr< ::apache::thrift::concurrency::Monitor> MonitorPtr;
typedef std::map<int32_t, MonitorPtr> MonitorMap;
public:

View file

@ -38,13 +38,14 @@ TEvhttpClientChannel::TEvhttpClientChannel(const std::string& host,
const std::string& path,
const char* address,
int port,
struct event_base* eb)
struct event_base* eb,
struct evdns_base* dnsbase)
: host_(host), path_(path), conn_(NULL) {
conn_ = evhttp_connection_new(address, port);
conn_ = evhttp_connection_base_new(eb, dnsbase, address, port);
if (conn_ == NULL) {
throw TException("evhttp_connection_new failed");
}
evhttp_connection_set_base(conn_, eb);
}
TEvhttpClientChannel::~TEvhttpClientChannel() {

View file

@ -23,10 +23,11 @@
#include <queue>
#include <string>
#include <utility>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
#include <thrift/async/TAsyncChannel.h>
struct event_base;
struct evdns_base;
struct evhttp_connection;
struct evhttp_request;
@ -50,7 +51,8 @@ public:
const std::string& path,
const char* address,
int port,
struct event_base* eb);
struct event_base* eb,
struct evdns_base *dnsbase = 0);
~TEvhttpClientChannel();
virtual void sendAndRecvMessage(const VoidCallback& cob,

View file

@ -20,10 +20,10 @@
#include <thrift/async/TEvhttpServer.h>
#include <thrift/async/TAsyncBufferProcessor.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/stdcxx.h>
#include <evhttp.h>
#include <event2/buffer.h>
#include <event2/buffer_compat.h>
#include <iostream>
#ifndef HTTP_INTERNAL // libevent < 2
@ -31,6 +31,8 @@
#endif
using apache::thrift::transport::TMemoryBuffer;
using apache::thrift::stdcxx::scoped_ptr;
using apache::thrift::stdcxx::shared_ptr;
namespace apache {
namespace thrift {
@ -38,17 +40,17 @@ 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;
stdcxx::shared_ptr<apache::thrift::transport::TMemoryBuffer> ibuf;
stdcxx::shared_ptr<apache::thrift::transport::TMemoryBuffer> obuf;
RequestContext(struct evhttp_request* req);
};
TEvhttpServer::TEvhttpServer(boost::shared_ptr<TAsyncBufferProcessor> processor)
TEvhttpServer::TEvhttpServer(stdcxx::shared_ptr<TAsyncBufferProcessor> processor)
: processor_(processor), eb_(NULL), eh_(NULL) {
}
TEvhttpServer::TEvhttpServer(boost::shared_ptr<TAsyncBufferProcessor> processor, int port)
TEvhttpServer::TEvhttpServer(stdcxx::shared_ptr<TAsyncBufferProcessor> processor, int port)
: processor_(processor), eb_(NULL), eh_(NULL) {
// Create event_base and evhttp.
eb_ = event_base_new();
@ -118,7 +120,7 @@ void TEvhttpServer::process(struct evhttp_request* req) {
void TEvhttpServer::complete(RequestContext* ctx, bool success) {
(void)success;
std::auto_ptr<RequestContext> ptr(ctx);
scoped_ptr<RequestContext> ptr(ctx);
int code = success ? 200 : 400;
const char* reason = success ? "OK" : "Bad Request";

View file

@ -20,7 +20,7 @@
#ifndef _THRIFT_TEVHTTP_SERVER_H_
#define _THRIFT_TEVHTTP_SERVER_H_ 1
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
struct event_base;
struct evhttp;
@ -41,14 +41,14 @@ public:
* address of the server as the extra arg.
* Do not call "serve" on this server.
*/
TEvhttpServer(boost::shared_ptr<TAsyncBufferProcessor> processor);
TEvhttpServer(stdcxx::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(stdcxx::shared_ptr<TAsyncBufferProcessor> processor, int port);
~TEvhttpServer();
@ -63,7 +63,7 @@ private:
void process(struct evhttp_request* req);
void complete(RequestContext* ctx, bool success);
boost::shared_ptr<TAsyncBufferProcessor> processor_;
stdcxx::shared_ptr<TAsyncBufferProcessor> processor_;
struct event_base* eb_;
struct evhttp* eh_;
};

View file

@ -23,9 +23,9 @@
#include <thrift/concurrency/Exception.h>
#include <thrift/concurrency/Util.h>
#include <thrift/transport/PlatformSocket.h>
#include <assert.h>
#include <thrift/stdcxx.h>
#include <boost/scoped_ptr.hpp>
#include <assert.h>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
@ -155,7 +155,7 @@ public:
private:
void init(Mutex* mutex) { mutex_ = mutex; }
boost::scoped_ptr<Mutex> ownedMutex_;
stdcxx::scoped_ptr<Mutex> ownedMutex_;
Mutex* mutex_;
};

View file

@ -33,7 +33,9 @@ namespace thrift {
namespace concurrency {
/**
* Implementation of Mutex class using boost interprocess mutex
* Implementation of Mutex class using boost::timed_mutex
*
* Methods throw boost::lock_error on error.
*
* @version $Id:$
*/

View file

@ -23,18 +23,20 @@
#include <thrift/concurrency/BoostThreadFactory.h>
#include <thrift/concurrency/Exception.h>
#include <thrift/stdcxx.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;
using stdcxx::bind;
using stdcxx::scoped_ptr;
using stdcxx::shared_ptr;
using stdcxx::weak_ptr;
namespace concurrency {
/**
* The boost thread class.
@ -48,7 +50,8 @@ public:
static void* threadMain(void* arg);
private:
std::auto_ptr<boost::thread> thread_;
scoped_ptr<boost::thread> thread_;
Monitor monitor_;
STATE state_;
weak_ptr<BoostThread> self_;
bool detached_;
@ -60,7 +63,7 @@ public:
}
~BoostThread() {
if (!detached_) {
if (!detached_ && thread_->joinable()) {
try {
join();
} catch (...) {
@ -69,26 +72,46 @@ public:
}
}
void start() {
if (state_ != uninitialized) {
return;
}
STATE getState() const
{
Synchronized sync(monitor_);
return state_;
}
void setState(STATE newState)
{
Synchronized sync(monitor_);
state_ = newState;
// unblock start() with the knowledge that the thread has actually
// started running, which avoids a race in detached threads.
if (newState == started) {
monitor_.notify();
}
}
void start() {
// Create reference
shared_ptr<BoostThread>* selfRef = new shared_ptr<BoostThread>();
*selfRef = self_.lock();
state_ = starting;
setState(starting);
thread_
= std::auto_ptr<boost::thread>(new boost::thread(boost::bind(threadMain, (void*)selfRef)));
Synchronized sync(monitor_);
thread_.reset(new boost::thread(bind(threadMain, (void*)selfRef)));
if (detached_)
thread_->detach();
// Wait for the thread to start and get far enough to grab everything
// that it needs from the calling context, thus absolving the caller
// from being required to hold on to runnable indefinitely.
monitor_.wait();
}
void join() {
if (!detached_ && state_ != uninitialized) {
if (!detached_ && getState() != uninitialized) {
thread_->join();
}
}
@ -109,19 +132,11 @@ 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->setState(started);
thread->runnable()->run();
if (thread->state_ != stopping && thread->state_ != stopped) {
thread->state_ = stopping;
if (thread->getState() != stopping && thread->getState() != stopped) {
thread->setState(stopping);
}
return (void*)0;
}

View file

@ -20,9 +20,9 @@
#ifndef _THRIFT_CONCURRENCY_BOOSTTHREADFACTORY_H_
#define _THRIFT_CONCURRENCY_BOOSTTHREADFACTORY_H_ 1
#include <thrift/concurrency/Monitor.h>
#include <thrift/concurrency/Thread.h>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
@ -38,9 +38,8 @@ 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.
* via stdcxx::shared_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.
@ -51,7 +50,7 @@ public:
BoostThreadFactory(bool detached = true);
// From ThreadFactory;
boost::shared_ptr<Thread> newThread(boost::shared_ptr<Runnable> runnable) const;
stdcxx::shared_ptr<Thread> newThread(stdcxx::shared_ptr<Runnable> runnable) const;
// From ThreadFactory;
Thread::id_t getCurrentThreadId() const;

View file

@ -20,8 +20,8 @@
#ifndef _THRIFT_CONCURRENCY_FUNCTION_RUNNER_H
#define _THRIFT_CONCURRENCY_FUNCTION_RUNNER_H 1
#include <thrift/cxxfunctional.h>
#include <thrift/concurrency/Thread.h>
#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
@ -53,20 +53,20 @@ 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 stdcxx::function<void()> VoidFunc;
typedef apache::thrift::stdcxx::function<bool()> BoolFunc;
typedef 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 stdcxx::shared_ptr<FunctionRunner> create(const VoidFunc& cob) {
return stdcxx::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));
static stdcxx::shared_ptr<FunctionRunner> create(PthreadFuncPtr func, void* arg) {
return stdcxx::shared_ptr<FunctionRunner>(new FunctionRunner(func, arg));
}
private:
@ -81,7 +81,7 @@ public:
* 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) {}
: func_(stdcxx::bind(pthread_func_wrapper, func, arg)), intervalMs_(-1) {}
/**
* Given a generic callback, this FunctionRunner will execute it.

View file

@ -23,8 +23,7 @@
#include <thrift/concurrency/Exception.h>
#include <thrift/concurrency/Util.h>
#include <thrift/transport/PlatformSocket.h>
#include <boost/scoped_ptr.hpp>
#include <thrift/stdcxx.h>
#include <assert.h>
@ -34,9 +33,11 @@
namespace apache {
namespace thrift {
namespace concurrency {
using boost::scoped_ptr;
using stdcxx::scoped_ptr;
using stdcxx::shared_ptr;
namespace concurrency {
/**
* Monitor implementation using the POSIX pthread library

View file

@ -17,25 +17,32 @@
* under the License.
*/
// needed to test for pthread implementation capabilities:
#define __USE_GNU
#include <thrift/thrift-config.h>
#include <thrift/Thrift.h>
#include <thrift/concurrency/Exception.h>
#include <thrift/concurrency/Mutex.h>
#include <thrift/concurrency/Util.h>
#include <assert.h>
#ifdef HAVE_PTHREAD_H
#include <stdlib.h>
#include <pthread.h>
#endif
#include <signal.h>
#include <string.h>
using boost::shared_ptr;
#include <boost/format.hpp>
namespace apache {
namespace thrift {
namespace concurrency {
#ifndef THRIFT_NO_CONTENTION_PROFILING
// Enable this to turn on mutex contention profiling support
// #define THRIFT_PTHREAD_MUTEX_CONTENTION_PROFILING
#ifdef THRIFT_PTHREAD_MUTEX_CONTENTION_PROFILING
static int32_t mutexProfilingCounter = 0;
static int32_t mutexProfilingSampleRate = 0;
@ -105,17 +112,25 @@ static inline int64_t maybeGetProfilingStartTime() {
#define PROFILE_MUTEX_LOCKED()
#define PROFILE_MUTEX_START_UNLOCK()
#define PROFILE_MUTEX_UNLOCKED()
#endif // THRIFT_NO_CONTENTION_PROFILING
#endif // THRIFT_PTHREAD_MUTEX_CONTENTION_PROFILING
#define EINTR_LOOP(_CALL) int ret; do { ret = _CALL; } while (ret == EINTR)
#define ABORT_ONFAIL(_CALL) { EINTR_LOOP(_CALL); if (ret) { abort(); } }
#define THROW_SRE(_CALLSTR, RET) { throw SystemResourceException(boost::str(boost::format("%1% returned %2% (%3%)") % _CALLSTR % RET % ::strerror(RET))); }
#define THROW_SRE_ONFAIL(_CALL) { EINTR_LOOP(_CALL); if (ret) { THROW_SRE(#_CALL, ret); } }
#define THROW_SRE_TRYFAIL(_CALL) { EINTR_LOOP(_CALL); if (ret == 0) { return true; } else if (ret == EBUSY) { return false; } THROW_SRE(#_CALL, ret); }
/**
* Implementation of Mutex class using POSIX mutex
*
* Throws apache::thrift::concurrency::SystemResourceException on error.
*
* @version $Id:$
*/
class Mutex::impl {
public:
impl(Initializer init) : initialized_(false) {
#ifndef THRIFT_NO_CONTENTION_PROFILING
#ifdef THRIFT_PTHREAD_MUTEX_CONTENTION_PROFILING
profileTime_ = 0;
#endif
init(&pthread_mutex_);
@ -125,19 +140,19 @@ public:
~impl() {
if (initialized_) {
initialized_ = false;
int ret = pthread_mutex_destroy(&pthread_mutex_);
THRIFT_UNUSED_VARIABLE(ret);
assert(ret == 0);
ABORT_ONFAIL(pthread_mutex_destroy(&pthread_mutex_));
}
}
void lock() const {
PROFILE_MUTEX_START_LOCK();
pthread_mutex_lock(&pthread_mutex_);
THROW_SRE_ONFAIL(pthread_mutex_lock(&pthread_mutex_));
PROFILE_MUTEX_LOCKED();
}
bool trylock() const { return (0 == pthread_mutex_trylock(&pthread_mutex_)); }
bool trylock() const {
THROW_SRE_TRYFAIL(pthread_mutex_trylock(&pthread_mutex_));
}
bool timedlock(int64_t milliseconds) const {
#if defined(_POSIX_TIMEOUTS) && _POSIX_TIMEOUTS >= 200112L
@ -145,14 +160,16 @@ public:
struct THRIFT_TIMESPEC ts;
Util::toTimespec(ts, milliseconds + Util::currentTime());
int ret = pthread_mutex_timedlock(&pthread_mutex_, &ts);
EINTR_LOOP(pthread_mutex_timedlock(&pthread_mutex_, &ts));
if (ret == 0) {
PROFILE_MUTEX_LOCKED();
return true;
} else if (ret == ETIMEDOUT) {
PROFILE_MUTEX_NOT_LOCKED();
return false;
}
PROFILE_MUTEX_NOT_LOCKED();
return false;
THROW_SRE("pthread_mutex_timedlock(&pthread_mutex_, &ts)", ret);
#else
/* Otherwise follow solution used by Mono for Android */
struct THRIFT_TIMESPEC sleepytime, now, to;
@ -177,7 +194,7 @@ public:
void unlock() const {
PROFILE_MUTEX_START_UNLOCK();
pthread_mutex_unlock(&pthread_mutex_);
THROW_SRE_ONFAIL(pthread_mutex_unlock(&pthread_mutex_));
PROFILE_MUTEX_UNLOCKED();
}
@ -186,7 +203,7 @@ public:
private:
mutable pthread_mutex_t pthread_mutex_;
mutable bool initialized_;
#ifndef THRIFT_NO_CONTENTION_PROFILING
#ifdef THRIFT_PTHREAD_MUTEX_CONTENTION_PROFILING
mutable int64_t profileTime_;
#endif
};
@ -216,28 +233,16 @@ void Mutex::unlock() const {
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);
THROW_SRE_ONFAIL(pthread_mutex_init(pthread_mutex, NULL));
}
#if defined(PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP) \
|| defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
#if defined(PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP) || defined(PTHREAD_ERRORCHECK_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);
THROW_SRE_ONFAIL(pthread_mutexattr_init(&mutexattr));
THROW_SRE_ONFAIL(pthread_mutexattr_settype(&mutexattr, kind));
THROW_SRE_ONFAIL(pthread_mutex_init(mutex, &mutexattr));
THROW_SRE_ONFAIL(pthread_mutexattr_destroy(&mutexattr));
}
#endif
@ -255,6 +260,12 @@ void Mutex::ADAPTIVE_INITIALIZER(void* arg) {
}
#endif
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
void Mutex::ERRORCHECK_INITIALIZER(void* arg) {
init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_ERRORCHECK);
}
#endif
#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
void Mutex::RECURSIVE_INITIALIZER(void* arg) {
init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_RECURSIVE_NP);
@ -269,50 +280,46 @@ void Mutex::RECURSIVE_INITIALIZER(void* arg) {
class ReadWriteMutex::impl {
public:
impl() : initialized_(false) {
#ifndef THRIFT_NO_CONTENTION_PROFILING
#ifdef THRIFT_PTHREAD_MUTEX_CONTENTION_PROFILING
profileTime_ = 0;
#endif
int ret = pthread_rwlock_init(&rw_lock_, NULL);
THRIFT_UNUSED_VARIABLE(ret);
assert(ret == 0);
THROW_SRE_ONFAIL(pthread_rwlock_init(&rw_lock_, NULL));
initialized_ = true;
}
~impl() {
if (initialized_) {
initialized_ = false;
int ret = pthread_rwlock_destroy(&rw_lock_);
THRIFT_UNUSED_VARIABLE(ret);
assert(ret == 0);
ABORT_ONFAIL(pthread_rwlock_destroy(&rw_lock_));
}
}
void acquireRead() const {
PROFILE_MUTEX_START_LOCK();
pthread_rwlock_rdlock(&rw_lock_);
THROW_SRE_ONFAIL(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_);
THROW_SRE_ONFAIL(pthread_rwlock_wrlock(&rw_lock_));
PROFILE_MUTEX_LOCKED();
}
bool attemptRead() const { return !pthread_rwlock_tryrdlock(&rw_lock_); }
bool attemptRead() const { THROW_SRE_TRYFAIL(pthread_rwlock_tryrdlock(&rw_lock_)); }
bool attemptWrite() const { return !pthread_rwlock_trywrlock(&rw_lock_); }
bool attemptWrite() const { THROW_SRE_TRYFAIL(pthread_rwlock_trywrlock(&rw_lock_)); }
void release() const {
PROFILE_MUTEX_START_UNLOCK();
pthread_rwlock_unlock(&rw_lock_);
THROW_SRE_ONFAIL(pthread_rwlock_unlock(&rw_lock_));
PROFILE_MUTEX_UNLOCKED();
}
private:
mutable pthread_rwlock_t rw_lock_;
mutable bool initialized_;
#ifndef THRIFT_NO_CONTENTION_PROFILING
#ifdef THRIFT_PTHREAD_MUTEX_CONTENTION_PROFILING
mutable int64_t profileTime_;
#endif
};

View file

@ -20,7 +20,7 @@
#ifndef _THRIFT_CONCURRENCY_MUTEX_H_
#define _THRIFT_CONCURRENCY_MUTEX_H_ 1
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
#include <boost/noncopyable.hpp>
#include <stdint.h>
@ -53,6 +53,11 @@ void enableMutexProfiling(int32_t profilingSampleRate, MutexWaitCallback callbac
#endif
/**
* NOTE: All mutex implementations throw an exception on failure. See each
* specific implementation to understand the exception type(s) used.
*/
/**
* A simple mutex class
*
@ -64,6 +69,7 @@ public:
Mutex(Initializer init = DEFAULT_INITIALIZER);
virtual ~Mutex() {}
virtual void lock() const;
virtual bool trylock() const;
virtual bool timedlock(int64_t milliseconds) const;
@ -71,13 +77,16 @@ public:
void* getUnderlyingImpl() const;
static void DEFAULT_INITIALIZER(void*);
// If you attempt to use one of these and it fails to link, it means
// your version of pthreads does not support it - try another one.
static void ADAPTIVE_INITIALIZER(void*);
static void DEFAULT_INITIALIZER(void*);
static void ERRORCHECK_INITIALIZER(void*);
static void RECURSIVE_INITIALIZER(void*);
private:
class impl;
boost::shared_ptr<impl> impl_;
stdcxx::shared_ptr<impl> impl_;
};
class ReadWriteMutex {
@ -98,7 +107,7 @@ public:
private:
class impl;
boost::shared_ptr<impl> impl_;
stdcxx::shared_ptr<impl> impl_;
};
/**

View file

@ -19,8 +19,9 @@
#include <thrift/thrift-config.h>
#include <thrift/concurrency/PosixThreadFactory.h>
#include <thrift/concurrency/Exception.h>
#include <thrift/concurrency/Monitor.h>
#include <thrift/concurrency/PosixThreadFactory.h>
#if GOOGLE_PERFTOOLS_REGISTER_THREAD
#include <google/profiler.h>
@ -31,15 +32,12 @@
#include <iostream>
#include <boost/weak_ptr.hpp>
#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
namespace concurrency {
using boost::shared_ptr;
using boost::weak_ptr;
/**
* The POSIX thread class.
*
@ -55,11 +53,12 @@ public:
private:
pthread_t pthread_;
STATE state_;
Monitor monitor_; // guard to protect state_ and also notification
STATE state_; // to protect proper thread start behavior
int policy_;
int priority_;
int stackSize_;
weak_ptr<PthreadThread> self_;
stdcxx::weak_ptr<PthreadThread> self_;
bool detached_;
public:
@ -67,13 +66,12 @@ public:
int priority,
int stackSize,
bool detached,
shared_ptr<Runnable> runnable)
stdcxx::shared_ptr<Runnable> runnable)
:
#ifndef _WIN32
pthread_(0),
#endif // _WIN32
state_(uninitialized),
policy_(policy),
priority_(priority),
@ -96,8 +94,26 @@ public:
}
}
STATE getState() const
{
Synchronized sync(monitor_);
return state_;
}
void setState(STATE newState)
{
Synchronized sync(monitor_);
state_ = newState;
// unblock start() with the knowledge that the thread has actually
// started running, which avoids a race in detached threads.
if (newState == started) {
monitor_.notify();
}
}
void start() {
if (state_ != uninitialized) {
if (getState() != uninitialized) {
return;
}
@ -139,18 +155,27 @@ public:
}
// Create reference
shared_ptr<PthreadThread>* selfRef = new shared_ptr<PthreadThread>();
stdcxx::shared_ptr<PthreadThread>* selfRef = new stdcxx::shared_ptr<PthreadThread>();
*selfRef = self_.lock();
state_ = starting;
setState(starting);
Synchronized sync(monitor_);
if (pthread_create(&pthread_, &thread_attr, threadMain, (void*)selfRef) != 0) {
throw SystemResourceException("pthread_create failed");
}
// The caller may not choose to guarantee the scope of the Runnable
// being used in the thread, so we must actually wait until the thread
// starts before we return. If we do not wait, it would be possible
// for the caller to start destructing the Runnable and the Thread,
// and we would end up in a race. This was identified with valgrind.
monitor_.wait();
}
void join() {
if (!detached_ && state_ != uninitialized) {
if (!detached_ && getState() != uninitialized) {
void* ignore;
/* XXX
If join fails it is most likely due to the fact
@ -164,8 +189,6 @@ public:
if (res != 0) {
GlobalOutput.printf("PthreadThread::join(): fail with code %d", res);
}
} else {
GlobalOutput.printf("PthreadThread::join(): detached thread");
}
}
@ -178,36 +201,31 @@ public:
#endif // _WIN32
}
shared_ptr<Runnable> runnable() const { return Thread::runnable(); }
stdcxx::shared_ptr<Runnable> runnable() const { return Thread::runnable(); }
void runnable(shared_ptr<Runnable> value) { Thread::runnable(value); }
void runnable(stdcxx::shared_ptr<Runnable> value) { Thread::runnable(value); }
void weakRef(shared_ptr<PthreadThread> self) {
void weakRef(stdcxx::shared_ptr<PthreadThread> self) {
assert(self.get() == this);
self_ = weak_ptr<PthreadThread>(self);
self_ = stdcxx::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;
}
stdcxx::shared_ptr<PthreadThread> thread = *(stdcxx::shared_ptr<PthreadThread>*)arg;
delete reinterpret_cast<stdcxx::shared_ptr<PthreadThread>*>(arg);
#if GOOGLE_PERFTOOLS_REGISTER_THREAD
ProfilerRegisterThread();
#endif
thread->state_ = started;
thread->setState(started);
thread->runnable()->run();
if (thread->state_ != stopping && thread->state_ != stopped) {
thread->state_ = stopping;
STATE _s = thread->getState();
if (_s != stopping && _s != stopped) {
thread->setState(stopping);
}
return (void*)0;
@ -276,9 +294,9 @@ PosixThreadFactory::PosixThreadFactory(bool detached)
stackSize_(1) {
}
shared_ptr<Thread> PosixThreadFactory::newThread(shared_ptr<Runnable> runnable) const {
shared_ptr<PthreadThread> result
= shared_ptr<PthreadThread>(new PthreadThread(toPthreadPolicy(policy_),
stdcxx::shared_ptr<Thread> PosixThreadFactory::newThread(stdcxx::shared_ptr<Runnable> runnable) const {
stdcxx::shared_ptr<PthreadThread> result
= stdcxx::shared_ptr<PthreadThread>(new PthreadThread(toPthreadPolicy(policy_),
toPthreadPriority(policy_, priority_),
stackSize_,
isDetached(),

View file

@ -22,7 +22,7 @@
#include <thrift/concurrency/Thread.h>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
@ -63,9 +63,9 @@ public:
/**
* 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.
* via stdcxx::shared_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
@ -88,7 +88,7 @@ public:
PosixThreadFactory(bool detached);
// From ThreadFactory;
boost::shared_ptr<Thread> newThread(boost::shared_ptr<Runnable> runnable) const;
stdcxx::shared_ptr<Thread> newThread(stdcxx::shared_ptr<Runnable> runnable) const;
// From ThreadFactory;
Thread::id_t getCurrentThreadId() const;

View file

@ -33,11 +33,14 @@ namespace concurrency {
/**
* Implementation of Mutex class using C++11 std::timed_mutex
*
* Methods throw std::system_error on error.
*
* @version $Id:$
*/
class Mutex::impl : public std::timed_mutex {};
Mutex::Mutex(Initializer init) : impl_(new Mutex::impl()) {
((void)init);
}
void* Mutex::getUnderlyingImpl() const {
@ -61,6 +64,7 @@ void Mutex::unlock() const {
}
void Mutex::DEFAULT_INITIALIZER(void* arg) {
((void)arg);
}
}
}

View file

@ -21,13 +21,12 @@
#if USE_STD_THREAD
#include <thrift/concurrency/StdThreadFactory.h>
#include <thrift/concurrency/Exception.h>
#include <thrift/concurrency/Monitor.h>
#include <thrift/concurrency/StdThreadFactory.h>
#include <thrift/stdcxx.h>
#include <cassert>
#include <boost/enable_shared_from_this.hpp>
#include <boost/weak_ptr.hpp>
#include <thread>
namespace apache {
@ -43,25 +42,26 @@ namespace concurrency {
*
* @version $Id:$
*/
class StdThread : public Thread, public boost::enable_shared_from_this<StdThread> {
class StdThread : public Thread, public stdcxx::enable_shared_from_this<StdThread> {
public:
enum STATE { uninitialized, starting, started, stopping, stopped };
static void threadMain(boost::shared_ptr<StdThread> thread);
static void threadMain(stdcxx::shared_ptr<StdThread> thread);
private:
std::unique_ptr<std::thread> thread_;
Monitor monitor_;
STATE state_;
bool detached_;
public:
StdThread(bool detached, boost::shared_ptr<Runnable> runnable)
StdThread(bool detached, stdcxx::shared_ptr<Runnable> runnable)
: state_(uninitialized), detached_(detached) {
this->Thread::runnable(runnable);
}
~StdThread() {
if (!detached_) {
if (!detached_ && thread_->joinable()) {
try {
join();
} catch (...) {
@ -70,18 +70,42 @@ public:
}
}
STATE getState() const
{
Synchronized sync(monitor_);
return state_;
}
void setState(STATE newState)
{
Synchronized sync(monitor_);
state_ = newState;
// unblock start() with the knowledge that the thread has actually
// started running, which avoids a race in detached threads.
if (newState == started) {
monitor_.notify();
}
}
void start() {
if (state_ != uninitialized) {
if (getState() != uninitialized) {
return;
}
boost::shared_ptr<StdThread> selfRef = shared_from_this();
state_ = starting;
stdcxx::shared_ptr<StdThread> selfRef = shared_from_this();
setState(starting);
Synchronized sync(monitor_);
thread_ = std::unique_ptr<std::thread>(new std::thread(threadMain, selfRef));
if (detached_)
thread_->detach();
// Wait for the thread to start and get far enough to grab everything
// that it needs from the calling context, thus absolving the caller
// from being required to hold on to runnable indefinitely.
monitor_.wait();
}
void join() {
@ -92,35 +116,29 @@ public:
Thread::id_t getId() { return thread_.get() ? thread_->get_id() : std::thread::id(); }
boost::shared_ptr<Runnable> runnable() const { return Thread::runnable(); }
stdcxx::shared_ptr<Runnable> runnable() const { return Thread::runnable(); }
void runnable(boost::shared_ptr<Runnable> value) { Thread::runnable(value); }
void runnable(stdcxx::shared_ptr<Runnable> value) { Thread::runnable(value); }
};
void StdThread::threadMain(boost::shared_ptr<StdThread> thread) {
if (thread == NULL) {
return;
}
void StdThread::threadMain(stdcxx::shared_ptr<StdThread> thread) {
#if GOOGLE_PERFTOOLS_REGISTER_THREAD
ProfilerRegisterThread();
#endif
if (thread->state_ != starting) {
return;
}
thread->state_ = started;
thread->setState(started);
thread->runnable()->run();
if (thread->state_ != stopping && thread->state_ != stopped) {
thread->state_ = stopping;
if (thread->getState() != stopping && thread->getState() != stopped) {
thread->setState(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));
stdcxx::shared_ptr<Thread> StdThreadFactory::newThread(stdcxx::shared_ptr<Runnable> runnable) const {
stdcxx::shared_ptr<StdThread> result = stdcxx::shared_ptr<StdThread>(new StdThread(isDetached(), runnable));
runnable->thread(result);
return result;
}

View file

@ -22,7 +22,7 @@
#include <thrift/concurrency/Thread.h>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
@ -38,8 +38,8 @@ 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
* via stdcxx::shared_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.
@ -48,7 +48,7 @@ public:
StdThreadFactory(bool detached = true);
// From ThreadFactory;
boost::shared_ptr<Thread> newThread(boost::shared_ptr<Runnable> runnable) const;
stdcxx::shared_ptr<Thread> newThread(stdcxx::shared_ptr<Runnable> runnable) const;
// From ThreadFactory;
Thread::id_t getCurrentThreadId() const;

View file

@ -21,8 +21,7 @@
#define _THRIFT_CONCURRENCY_THREAD_H_ 1
#include <stdint.h>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <thrift/stdcxx.h>
#include <thrift/thrift-config.h>
@ -57,16 +56,16 @@ public:
* 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(); }
virtual stdcxx::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; }
virtual void thread(stdcxx::shared_ptr<Thread> value) { thread_ = value; }
private:
boost::weak_ptr<Thread> thread_;
stdcxx::weak_ptr<Thread> thread_;
};
/**
@ -122,13 +121,13 @@ public:
/**
* Gets the runnable object this thread is hosting
*/
virtual boost::shared_ptr<Runnable> runnable() const { return _runnable; }
virtual stdcxx::shared_ptr<Runnable> runnable() const { return _runnable; }
protected:
virtual void runnable(boost::shared_ptr<Runnable> value) { _runnable = value; }
virtual void runnable(stdcxx::shared_ptr<Runnable> value) { _runnable = value; }
private:
boost::shared_ptr<Runnable> _runnable;
stdcxx::shared_ptr<Runnable> _runnable;
};
/**
@ -155,7 +154,7 @@ public:
/**
* Create a new thread.
*/
virtual boost::shared_ptr<Thread> newThread(boost::shared_ptr<Runnable> runnable) const = 0;
virtual stdcxx::shared_ptr<Thread> newThread(stdcxx::shared_ptr<Runnable> runnable) const = 0;
/**
* Gets the current thread id or unknown_thread_id if the current thread is not a thrift thread

View file

@ -24,22 +24,18 @@
#include <thrift/concurrency/Monitor.h>
#include <thrift/concurrency/Util.h>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
#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;
using stdcxx::shared_ptr;
using stdcxx::dynamic_pointer_cast;
/**
* ThreadManager class
@ -508,7 +504,7 @@ void ThreadManager::Impl::remove(shared_ptr<Runnable> task) {
}
}
boost::shared_ptr<Runnable> ThreadManager::Impl::removeNextPending() {
stdcxx::shared_ptr<Runnable> ThreadManager::Impl::removeNextPending() {
Guard g(mutex_);
if (state_ != ThreadManager::STARTED) {
throw IllegalStateException(
@ -517,7 +513,7 @@ boost::shared_ptr<Runnable> ThreadManager::Impl::removeNextPending() {
}
if (tasks_.empty()) {
return boost::shared_ptr<Runnable>();
return stdcxx::shared_ptr<Runnable>();
}
shared_ptr<ThreadManager::Task> task = tasks_.front();

View file

@ -20,10 +20,9 @@
#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>
#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
@ -59,7 +58,7 @@ protected:
ThreadManager() {}
public:
typedef apache::thrift::stdcxx::function<void(boost::shared_ptr<Runnable>)> ExpireCallback;
typedef apache::thrift::stdcxx::function<void(stdcxx::shared_ptr<Runnable>)> ExpireCallback;
virtual ~ThreadManager() {}
@ -88,14 +87,14 @@ public:
/**
* \returns the current thread factory
*/
virtual boost::shared_ptr<ThreadFactory> threadFactory() const = 0;
virtual stdcxx::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;
virtual void threadFactory(stdcxx::shared_ptr<ThreadFactory> value) = 0;
/**
* Adds worker thread(s).
@ -162,21 +161,21 @@ public:
*
* @throws TooManyPendingTasksException Pending task count exceeds max pending task count
*/
virtual void add(boost::shared_ptr<Runnable> task,
virtual void add(stdcxx::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;
virtual void remove(stdcxx::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;
virtual stdcxx::shared_ptr<Runnable> removeNextPending() = 0;
/**
* Remove tasks from front of task queue that have expired.
@ -191,14 +190,14 @@ public:
*/
virtual void setExpireCallback(ExpireCallback expireCallback) = 0;
static boost::shared_ptr<ThreadManager> newThreadManager();
static stdcxx::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,
static stdcxx::shared_ptr<ThreadManager> newSimpleThreadManager(size_t count = 4,
size_t pendingTaskCountMax = 0);
class Task;

View file

@ -29,7 +29,8 @@ namespace apache {
namespace thrift {
namespace concurrency {
using boost::shared_ptr;
using stdcxx::shared_ptr;
using stdcxx::weak_ptr;
/**
* TimerManager class
@ -52,6 +53,10 @@ public:
}
}
bool operator==(const shared_ptr<Runnable> & runnable) const { return runnable_ == runnable; }
task_iterator it_;
private:
shared_ptr<Runnable> runnable_;
friend class TimerManager::Dispatcher;
@ -106,6 +111,7 @@ public:
for (task_iterator ix = manager_->taskMap_.begin(); ix != expiredTaskEnd; ix++) {
shared_ptr<TimerManager::Task> task = ix->second;
expiredTasks.insert(task);
task->it_ = manager_->taskMap_.end();
if (task->state_ == TimerManager::Task::WAITING) {
task->state_ = TimerManager::Task::EXECUTING;
}
@ -233,7 +239,7 @@ size_t TimerManager::taskCount() const {
return taskCount_;
}
void TimerManager::add(shared_ptr<Runnable> task, int64_t timeout) {
TimerManager::Timer TimerManager::add(shared_ptr<Runnable> task, int64_t timeout) {
int64_t now = Util::currentTime();
timeout += now;
@ -248,9 +254,9 @@ void TimerManager::add(shared_ptr<Runnable> task, int64_t timeout) {
// because the new task might insert at the front.
bool notifyRequired = (taskCount_ == 0) ? true : timeout < taskMap_.begin()->first;
shared_ptr<Task> timer(new Task(task));
taskCount_++;
taskMap_.insert(
std::pair<int64_t, shared_ptr<Task> >(timeout, shared_ptr<Task>(new Task(task))));
timer->it_ = taskMap_.insert(std::pair<int64_t, shared_ptr<Task> >(timeout, timer));
// 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
@ -258,10 +264,13 @@ void TimerManager::add(shared_ptr<Runnable> task, int64_t timeout) {
if (notifyRequired) {
monitor_.notify();
}
return timer;
}
}
void TimerManager::add(shared_ptr<Runnable> task, const struct THRIFT_TIMESPEC& value) {
TimerManager::Timer TimerManager::add(shared_ptr<Runnable> task,
const struct THRIFT_TIMESPEC& value) {
int64_t expiration;
Util::toMilliseconds(expiration, value);
@ -272,10 +281,11 @@ void TimerManager::add(shared_ptr<Runnable> task, const struct THRIFT_TIMESPEC&
throw InvalidArgumentException();
}
add(task, expiration - now);
return add(task, expiration - now);
}
void TimerManager::add(shared_ptr<Runnable> task, const struct timeval& value) {
TimerManager::Timer TimerManager::add(shared_ptr<Runnable> task,
const struct timeval& value) {
int64_t expiration;
Util::toMilliseconds(expiration, value);
@ -286,15 +296,47 @@ void TimerManager::add(shared_ptr<Runnable> task, const struct timeval& value) {
throw InvalidArgumentException();
}
add(task, expiration - now);
return add(task, expiration - now);
}
void TimerManager::remove(shared_ptr<Runnable> task) {
(void)task;
Synchronized s(monitor_);
if (state_ != TimerManager::STARTED) {
throw IllegalStateException();
}
bool found = false;
for (task_iterator ix = taskMap_.begin(); ix != taskMap_.end();) {
if (*ix->second == task) {
found = true;
taskCount_--;
taskMap_.erase(ix++);
} else {
++ix;
}
}
if (!found) {
throw NoSuchTaskException();
}
}
void TimerManager::remove(Timer handle) {
Synchronized s(monitor_);
if (state_ != TimerManager::STARTED) {
throw IllegalStateException();
}
shared_ptr<Task> task = handle.lock();
if (!task) {
throw NoSuchTaskException();
}
if (task->it_ == taskMap_.end()) {
// Task is being executed
throw UncancellableTaskException();
}
taskMap_.erase(task->it_);
taskCount_--;
}
TimerManager::STATE TimerManager::state() const {

View file

@ -24,7 +24,7 @@
#include <thrift/concurrency/Monitor.h>
#include <thrift/concurrency/Thread.h>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
#include <map>
#include <time.h>
@ -42,13 +42,16 @@ namespace concurrency {
class TimerManager {
public:
class Task;
typedef stdcxx::weak_ptr<Task> Timer;
TimerManager();
virtual ~TimerManager();
virtual boost::shared_ptr<const ThreadFactory> threadFactory() const;
virtual stdcxx::shared_ptr<const ThreadFactory> threadFactory() const;
virtual void threadFactory(boost::shared_ptr<const ThreadFactory> value);
virtual void threadFactory(stdcxx::shared_ptr<const ThreadFactory> value);
/**
* Starts the timer manager service
@ -69,28 +72,33 @@ public:
*
* @param task The task to execute
* @param timeout Time in milliseconds to delay before executing task
* @return Handle of the timer, which can be used to remove the timer.
*/
virtual void add(boost::shared_ptr<Runnable> task, int64_t timeout);
virtual Timer add(stdcxx::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.
* @return Handle of the timer, which can be used to remove the timer.
*/
virtual void add(boost::shared_ptr<Runnable> task, const struct THRIFT_TIMESPEC& timeout);
virtual Timer add(stdcxx::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.
* @return Handle of the timer, which can be used to remove the timer.
*/
virtual void add(boost::shared_ptr<Runnable> task, const struct timeval& timeout);
virtual Timer add(stdcxx::shared_ptr<Runnable> task, const struct timeval& timeout);
/**
* Removes a pending task
*
* @param task The task to remove. All timers which execute this task will
* be removed.
* @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
@ -98,25 +106,38 @@ public:
* @throws UncancellableTaskException Specified task is already being
* executed or has completed execution.
*/
virtual void remove(boost::shared_ptr<Runnable> task);
virtual void remove(stdcxx::shared_ptr<Runnable> task);
/**
* Removes a single pending task
*
* @param timer The timer to remove. The timer is returned when calling the
* add() method.
* @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(Timer timer);
enum STATE { UNINITIALIZED, STARTING, STARTED, STOPPING, STOPPED };
virtual STATE state() const;
private:
boost::shared_ptr<const ThreadFactory> threadFactory_;
class Task;
stdcxx::shared_ptr<const ThreadFactory> threadFactory_;
friend class Task;
std::multimap<int64_t, boost::shared_ptr<Task> > taskMap_;
std::multimap<int64_t, stdcxx::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;
stdcxx::shared_ptr<Dispatcher> dispatcher_;
stdcxx::shared_ptr<Thread> dispatcherThread_;
typedef std::multimap<int64_t, stdcxx::shared_ptr<TimerManager::Task> >::iterator task_iterator;
typedef std::pair<task_iterator, task_iterator> task_range;
};
}

View file

@ -1,132 +0,0 @@
/*
* 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_

View file

@ -34,26 +34,26 @@ PeekProcessor::PeekProcessor() {
PeekProcessor::~PeekProcessor() {
}
void PeekProcessor::initialize(boost::shared_ptr<TProcessor> actualProcessor,
boost::shared_ptr<TProtocolFactory> protocolFactory,
boost::shared_ptr<TPipedTransportFactory> transportFactory) {
void PeekProcessor::initialize(stdcxx::shared_ptr<TProcessor> actualProcessor,
stdcxx::shared_ptr<TProtocolFactory> protocolFactory,
stdcxx::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) {
stdcxx::shared_ptr<TTransport> PeekProcessor::getPipedTransport(stdcxx::shared_ptr<TTransport> in) {
return transportFactory_->getTransport(in);
}
void PeekProcessor::setTargetTransport(boost::shared_ptr<TTransport> targetTransport) {
void PeekProcessor::setTargetTransport(stdcxx::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 (stdcxx::dynamic_pointer_cast<TMemoryBuffer>(targetTransport_)) {
memoryBuffer_ = stdcxx::dynamic_pointer_cast<TMemoryBuffer>(targetTransport);
} else if (stdcxx::dynamic_pointer_cast<TPipedTransport>(targetTransport_)) {
memoryBuffer_ = stdcxx::dynamic_pointer_cast<TMemoryBuffer>(
stdcxx::dynamic_pointer_cast<TPipedTransport>(targetTransport_)->getTargetTransport());
}
if (!memoryBuffer_) {
@ -62,8 +62,8 @@ void PeekProcessor::setTargetTransport(boost::shared_ptr<TTransport> targetTrans
}
}
bool PeekProcessor::process(boost::shared_ptr<TProtocol> in,
boost::shared_ptr<TProtocol> out,
bool PeekProcessor::process(stdcxx::shared_ptr<TProtocol> in,
stdcxx::shared_ptr<TProtocol> out,
void* connectionContext) {
std::string fname;
@ -120,7 +120,7 @@ void PeekProcessor::peekBuffer(uint8_t* buffer, uint32_t size) {
(void)size;
}
void PeekProcessor::peek(boost::shared_ptr<TProtocol> in, TType ftype, int16_t fid) {
void PeekProcessor::peek(stdcxx::shared_ptr<TProtocol> in, TType ftype, int16_t fid) {
(void)fid;
in->skip(ftype);
}

View file

@ -25,7 +25,7 @@
#include <thrift/transport/TTransport.h>
#include <thrift/transport/TTransportUtils.h>
#include <thrift/transport/TBufferTransports.h>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
@ -47,34 +47,34 @@ public:
// 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);
stdcxx::shared_ptr<apache::thrift::TProcessor> actualProcessor,
stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory> protocolFactory,
stdcxx::shared_ptr<apache::thrift::transport::TPipedTransportFactory> transportFactory);
boost::shared_ptr<apache::thrift::transport::TTransport> getPipedTransport(
boost::shared_ptr<apache::thrift::transport::TTransport> in);
stdcxx::shared_ptr<apache::thrift::transport::TTransport> getPipedTransport(
stdcxx::shared_ptr<apache::thrift::transport::TTransport> in);
void setTargetTransport(boost::shared_ptr<apache::thrift::transport::TTransport> targetTransport);
void setTargetTransport(stdcxx::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,
virtual bool process(stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> in,
stdcxx::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,
virtual void peek(stdcxx::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_;
stdcxx::shared_ptr<apache::thrift::TProcessor> actualProcessor_;
stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> pipedProtocol_;
stdcxx::shared_ptr<apache::thrift::transport::TPipedTransportFactory> transportFactory_;
stdcxx::shared_ptr<apache::thrift::transport::TMemoryBuffer> memoryBuffer_;
stdcxx::shared_ptr<apache::thrift::transport::TTransport> targetTransport_;
};
}
}

View file

@ -20,7 +20,7 @@
#ifndef STATSPROCESSOR_H
#define STATSPROCESSOR_H
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
#include <thrift/transport/TTransport.h>
#include <thrift/protocol/TProtocol.h>
#include <TProcessor.h>
@ -38,8 +38,8 @@ 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,
virtual bool process(stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> piprot,
stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> poprot,
void* serverContext) {
piprot_ = piprot;
@ -229,7 +229,7 @@ protected:
}
}
boost::shared_ptr<apache::thrift::protocol::TProtocol> piprot_;
stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> piprot_;
std::map<std::string, int64_t> frequency_map_;
bool print_;

View file

@ -27,8 +27,6 @@
namespace apache {
namespace thrift {
using boost::shared_ptr;
namespace protocol {
/**
@ -38,7 +36,7 @@ namespace protocol {
*/
class StoredMessageProtocol : public TProtocolDecorator {
public:
StoredMessageProtocol(shared_ptr<protocol::TProtocol> _protocol,
StoredMessageProtocol(stdcxx::shared_ptr<protocol::TProtocol> _protocol,
const std::string& _name,
const TMessageType _type,
const int32_t _seqid)
@ -67,19 +65,19 @@ public:
* processors with it, as shown in the following example:</p>
*
* <blockquote><code>
* shared_ptr<TMultiplexedProcessor> processor(new TMultiplexedProcessor());
* stdcxx::shared_ptr<TMultiplexedProcessor> processor(new TMultiplexedProcessor());
*
* processor->registerProcessor(
* "Calculator",
* shared_ptr<TProcessor>( new CalculatorProcessor(
* shared_ptr<CalculatorHandler>( new CalculatorHandler()))));
* stdcxx::shared_ptr<TProcessor>( new CalculatorProcessor(
* stdcxx::shared_ptr<CalculatorHandler>( new CalculatorHandler()))));
*
* processor->registerProcessor(
* "WeatherReport",
* shared_ptr<TProcessor>( new WeatherReportProcessor(
* shared_ptr<WeatherReportHandler>( new WeatherReportHandler()))));
* stdcxx::shared_ptr<TProcessor>( new WeatherReportProcessor(
* stdcxx::shared_ptr<WeatherReportHandler>( new WeatherReportHandler()))));
*
* shared_ptr<TServerTransport> transport(new TServerSocket(9090));
* stdcxx::shared_ptr<TServerTransport> transport(new TServerSocket(9090));
* TSimpleServer server(processor, transport);
*
* server.serve();
@ -87,7 +85,7 @@ public:
*/
class TMultiplexedProcessor : public TProcessor {
public:
typedef std::map<std::string, shared_ptr<TProcessor> > services_t;
typedef std::map<std::string, stdcxx::shared_ptr<TProcessor> > services_t;
/**
* 'Register' a service with this <code>TMultiplexedProcessor</code>. This
@ -100,10 +98,40 @@ public:
* as "handlers", e.g. WeatherReportHandler,
* implementing WeatherReportIf interface.
*/
void registerProcessor(const std::string& serviceName, shared_ptr<TProcessor> processor) {
void registerProcessor(const std::string& serviceName, stdcxx::shared_ptr<TProcessor> processor) {
services[serviceName] = processor;
}
/**
* Register a service to be called to process queries without service name
* \param [in] processor Implementation of a service.
*/
void registerDefault(const stdcxx::shared_ptr<TProcessor>& processor) {
defaultProcessor = processor;
}
/**
* Chew up invalid input and return an exception to throw.
*/
TException protocol_error(stdcxx::shared_ptr<protocol::TProtocol> in,
stdcxx::shared_ptr<protocol::TProtocol> out,
const std::string& name,
int32_t seqid,
const std::string& msg) const {
in->skip(::apache::thrift::protocol::T_STRUCT);
in->readMessageEnd();
in->getTransport()->readEnd();
::apache::thrift::TApplicationException
x(::apache::thrift::TApplicationException::PROTOCOL_ERROR,
"TMultiplexedProcessor: " + msg);
out->writeMessageBegin(name, ::apache::thrift::protocol::T_EXCEPTION, seqid);
x.write(out.get());
out->writeMessageEnd();
out->getTransport()->writeEnd();
out->getTransport()->flush();
return TException(msg);
}
/**
* This implementation of <code>process</code> performs the following steps:
*
@ -119,8 +147,8 @@ public:
* 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,
bool process(stdcxx::shared_ptr<protocol::TProtocol> in,
stdcxx::shared_ptr<protocol::TProtocol> out,
void* connectionContext) {
std::string name;
protocol::TMessageType type;
@ -133,22 +161,10 @@ public:
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);
throw protocol_error(in, out, name, seqid, "Unexpected message type");
}
// Extract the service name
boost::tokenizer<boost::char_separator<char> > tok(name, boost::char_separator<char>(":"));
std::vector<std::string> tokens;
@ -161,39 +177,46 @@ public:
services_t::iterator it = services.find(tokens[0]);
if (it != services.end()) {
shared_ptr<TProcessor> processor = it->second;
stdcxx::shared_ptr<TProcessor> processor = it->second;
// Let the processor registered for this service name
// process the message.
return processor
->process(shared_ptr<protocol::TProtocol>(
->process(stdcxx::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);
throw protocol_error(in, out, name, seqid,
"Unknown service: " + tokens[0] +
". Did you forget to call registerProcessor()?");
}
} else if (tokens.size() == 1) {
if (defaultProcessor) {
// non-multiplexed client forwards to default processor
return defaultProcessor
->process(stdcxx::shared_ptr<protocol::TProtocol>(
new protocol::StoredMessageProtocol(in, tokens[0], type, seqid)),
out,
connectionContext);
} else {
throw protocol_error(in, out, name, seqid,
"Non-multiplexed client request dropped. "
"Did you forget to call defaultProcessor()?");
}
} else {
throw protocol_error(in, out, name, seqid,
"Wrong number of tokens.");
}
return false;
}
private:
/** Map of service processor objects, indexed by service names. */
services_t services;
//! If a non-multi client requests something, it goes to the
//! default processor (if one is defined) for backwards compatibility.
stdcxx::shared_ptr<TProcessor> defaultProcessor;
};
}
}

View file

@ -23,7 +23,7 @@
#include <thrift/protocol/TProtocol.h>
#include <thrift/protocol/TVirtualProtocol.h>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
@ -41,7 +41,7 @@ public:
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)
TBinaryProtocolT(stdcxx::shared_ptr<Transport_> trans)
: TVirtualProtocol<TBinaryProtocolT<Transport_, ByteOrder_> >(trans),
trans_(trans.get()),
string_limit_(0),
@ -49,7 +49,7 @@ public:
strict_read_(false),
strict_write_(true) {}
TBinaryProtocolT(boost::shared_ptr<Transport_> trans,
TBinaryProtocolT(stdcxx::shared_ptr<Transport_> trans,
int32_t string_limit,
int32_t container_limit,
bool strict_read,
@ -212,8 +212,8 @@ public:
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);
stdcxx::shared_ptr<TProtocol> getProtocol(stdcxx::shared_ptr<TTransport> trans) {
stdcxx::shared_ptr<Transport_> specific_trans = stdcxx::dynamic_pointer_cast<Transport_>(trans);
TProtocol* prot;
if (specific_trans) {
prot = new TBinaryProtocolT<Transport_, ByteOrder_>(specific_trans,
@ -229,7 +229,7 @@ public:
strict_write_);
}
return boost::shared_ptr<TProtocol>(prot);
return stdcxx::shared_ptr<TProtocol>(prot);
}
private:

View file

@ -23,7 +23,7 @@
#include <thrift/protocol/TVirtualProtocol.h>
#include <stack>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
@ -74,7 +74,7 @@ protected:
int16_t lastFieldId_;
public:
TCompactProtocolT(boost::shared_ptr<Transport_> trans)
TCompactProtocolT(stdcxx::shared_ptr<Transport_> trans)
: TVirtualProtocol<TCompactProtocolT<Transport_> >(trans),
trans_(trans.get()),
lastFieldId_(0),
@ -86,7 +86,7 @@ public:
boolValue_.hasBoolValue = false;
}
TCompactProtocolT(boost::shared_ptr<Transport_> trans,
TCompactProtocolT(stdcxx::shared_ptr<Transport_> trans,
int32_t string_limit,
int32_t container_limit)
: TVirtualProtocol<TCompactProtocolT<Transport_> >(trans),
@ -239,8 +239,8 @@ public:
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);
stdcxx::shared_ptr<TProtocol> getProtocol(stdcxx::shared_ptr<TTransport> trans) {
stdcxx::shared_ptr<Transport_> specific_trans = stdcxx::dynamic_pointer_cast<Transport_>(trans);
TProtocol* prot;
if (specific_trans) {
prot = new TCompactProtocolT<Transport_>(specific_trans, string_limit_, container_limit_);
@ -248,7 +248,7 @@ public:
prot = new TCompactProtocol(trans, string_limit_, container_limit_);
}
return boost::shared_ptr<TProtocol>(prot);
return stdcxx::shared_ptr<TProtocol>(prot);
}
private:

View file

@ -387,7 +387,7 @@ uint32_t TCompactProtocolT<Transport_>::writeVarint64(uint64_t n) {
*/
template <class Transport_>
uint64_t TCompactProtocolT<Transport_>::i64ToZigzag(const int64_t l) {
return (l << 1) ^ (l >> 63);
return (static_cast<uint64_t>(l) << 1) ^ (l >> 63);
}
/**
@ -396,7 +396,7 @@ uint64_t TCompactProtocolT<Transport_>::i64ToZigzag(const int64_t l) {
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::i32ToZigzag(const int32_t n) {
return (n << 1) ^ (n >> 31);
return (static_cast<uint32_t>(n) << 1) ^ (n >> 31);
}
/**

View file

@ -19,12 +19,12 @@
#include <thrift/protocol/TDebugProtocol.h>
#include <thrift/TToString.h>
#include <cassert>
#include <cctype>
#include <cstdio>
#include <stdexcept>
#include <boost/static_assert.hpp>
#include <boost/lexical_cast.hpp>
using std::string;
@ -129,7 +129,7 @@ uint32_t TDebugProtocol::startItem() {
case MAP_VALUE:
return writePlain(" -> ");
case LIST:
size = writeIndented("[" + boost::lexical_cast<string>(list_idx_.back()) + "] = ");
size = writeIndented("[" + to_string(list_idx_.back()) + "] = ");
list_idx_.back()++;
return size;
default:
@ -223,7 +223,7 @@ 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);
string id_str = to_string(fieldId);
if (id_str.length() == 1)
id_str = '0' + id_str;
@ -248,7 +248,7 @@ uint32_t TDebugProtocol::writeMapBegin(const TType keyType,
bsize += startItem();
bsize += writePlain(
"map<" + fieldTypeName(keyType) + "," + fieldTypeName(valType) + ">"
"[" + boost::lexical_cast<string>(size) + "] {\n");
"[" + to_string(size) + "] {\n");
indentUp();
write_state_.push_back(MAP_KEY);
return bsize;
@ -269,7 +269,7 @@ uint32_t TDebugProtocol::writeListBegin(const TType elemType, const uint32_t siz
bsize += startItem();
bsize += writePlain(
"list<" + fieldTypeName(elemType) + ">"
"[" + boost::lexical_cast<string>(size) + "] {\n");
"[" + to_string(size) + "] {\n");
indentUp();
write_state_.push_back(LIST);
list_idx_.push_back(0);
@ -292,7 +292,7 @@ uint32_t TDebugProtocol::writeSetBegin(const TType elemType, const uint32_t size
bsize += startItem();
bsize += writePlain(
"set<" + fieldTypeName(elemType) + ">"
"[" + boost::lexical_cast<string>(size) + "] {\n");
"[" + to_string(size) + "] {\n");
indentUp();
write_state_.push_back(SET);
return bsize;
@ -316,19 +316,19 @@ uint32_t TDebugProtocol::writeByte(const int8_t byte) {
}
uint32_t TDebugProtocol::writeI16(const int16_t i16) {
return writeItem(boost::lexical_cast<string>(i16));
return writeItem(to_string(i16));
}
uint32_t TDebugProtocol::writeI32(const int32_t i32) {
return writeItem(boost::lexical_cast<string>(i32));
return writeItem(to_string(i32));
}
uint32_t TDebugProtocol::writeI64(const int64_t i64) {
return writeItem(boost::lexical_cast<string>(i64));
return writeItem(to_string(i64));
}
uint32_t TDebugProtocol::writeDouble(const double dub) {
return writeItem(boost::lexical_cast<string>(dub));
return writeItem(to_string(dub));
}
uint32_t TDebugProtocol::writeString(const string& str) {
@ -337,7 +337,7 @@ uint32_t TDebugProtocol::writeString(const string& str) {
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()) + ")";
to_show += "[...](" + to_string(str.length()) + ")";
}
string output = "\"";

View file

@ -22,7 +22,7 @@
#include <thrift/protocol/TVirtualProtocol.h>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
@ -51,7 +51,7 @@ private:
enum write_state_t { UNINIT, STRUCT, LIST, SET, MAP_KEY, MAP_VALUE };
public:
TDebugProtocol(boost::shared_ptr<TTransport> trans)
TDebugProtocol(stdcxx::shared_ptr<TTransport> trans)
: TVirtualProtocol<TDebugProtocol>(trans),
trans_(trans.get()),
string_limit_(DEFAULT_STRING_LIMIT),
@ -141,8 +141,8 @@ public:
TDebugProtocolFactory() {}
virtual ~TDebugProtocolFactory() {}
boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) {
return boost::shared_ptr<TProtocol>(new TDebugProtocol(trans));
stdcxx::shared_ptr<TProtocol> getProtocol(stdcxx::shared_ptr<TTransport> trans) {
return stdcxx::shared_ptr<TProtocol>(new TDebugProtocol(trans));
}
};
}
@ -160,7 +160,7 @@ 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);
stdcxx::shared_ptr<TTransport> trans(buffer);
TDebugProtocol protocol(trans);
ts.write(&protocol);
@ -178,7 +178,7 @@ 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);
stdcxx::shared_ptr<TTransport> trans(buffer);
TDebugProtocol protocol(trans);
// I am gross!

View file

@ -27,7 +27,7 @@
#include <limits>
#include <boost/static_assert.hpp>
#include <boost/make_shared.hpp>
#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
@ -42,11 +42,11 @@ void THeaderProtocol::resetProtocol() {
switch (protoId_) {
case T_BINARY_PROTOCOL:
proto_ = boost::make_shared<TBinaryProtocolT<THeaderTransport> >(trans_);
proto_ = stdcxx::make_shared<TBinaryProtocolT<THeaderTransport> >(trans_);
break;
case T_COMPACT_PROTOCOL:
proto_ = boost::make_shared<TCompactProtocolT<THeaderTransport> >(trans_);
proto_ = stdcxx::make_shared<TCompactProtocolT<THeaderTransport> >(trans_);
break;
default:

View file

@ -25,7 +25,7 @@
#include <thrift/protocol/TVirtualProtocol.h>
#include <thrift/transport/THeaderTransport.h>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
using apache::thrift::transport::THeaderTransport;
@ -43,21 +43,21 @@ protected:
public:
void resetProtocol();
explicit THeaderProtocol(const boost::shared_ptr<TTransport>& trans,
explicit THeaderProtocol(const stdcxx::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())),
: TVirtualProtocol<THeaderProtocol>(stdcxx::shared_ptr<TTransport>(new THeaderTransport(trans))),
trans_(stdcxx::dynamic_pointer_cast<THeaderTransport>(getTransport())),
protoId_(protoId) {
trans_->setProtocolId(protoId);
resetProtocol();
}
THeaderProtocol(const boost::shared_ptr<TTransport>& inTrans,
const boost::shared_ptr<TTransport>& outTrans,
THeaderProtocol(const stdcxx::shared_ptr<TTransport>& inTrans,
const stdcxx::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())),
stdcxx::shared_ptr<TTransport>(new THeaderTransport(inTrans, outTrans))),
trans_(stdcxx::dynamic_pointer_cast<THeaderTransport>(getTransport())),
protoId_(protoId) {
trans_->setProtocolId(protoId);
resetProtocol();
@ -182,25 +182,25 @@ public:
uint32_t readBinary(std::string& binary);
protected:
boost::shared_ptr<THeaderTransport> trans_;
stdcxx::shared_ptr<THeaderTransport> trans_;
boost::shared_ptr<TProtocol> proto_;
stdcxx::shared_ptr<TProtocol> proto_;
uint32_t protoId_;
};
class THeaderProtocolFactory : public TProtocolFactory {
public:
virtual boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<transport::TTransport> trans) {
virtual stdcxx::shared_ptr<TProtocol> getProtocol(stdcxx::shared_ptr<transport::TTransport> trans) {
THeaderProtocol* headerProtocol
= new THeaderProtocol(trans, boost::shared_ptr<transport::TTransport>(), T_BINARY_PROTOCOL);
return boost::shared_ptr<TProtocol>(headerProtocol);
= new THeaderProtocol(trans, trans, T_BINARY_PROTOCOL);
return stdcxx::shared_ptr<TProtocol>(headerProtocol);
}
virtual boost::shared_ptr<TProtocol> getProtocol(
boost::shared_ptr<transport::TTransport> inTrans,
boost::shared_ptr<transport::TTransport> outTrans) {
virtual stdcxx::shared_ptr<TProtocol> getProtocol(
stdcxx::shared_ptr<transport::TTransport> inTrans,
stdcxx::shared_ptr<transport::TTransport> outTrans) {
THeaderProtocol* headerProtocol = new THeaderProtocol(inTrans, outTrans, T_BINARY_PROTOCOL);
return boost::shared_ptr<TProtocol>(headerProtocol);
return stdcxx::shared_ptr<TProtocol>(headerProtocol);
}
};
}

View file

@ -19,9 +19,9 @@
#include <thrift/protocol/TJSONProtocol.h>
#include <boost/lexical_cast.hpp>
#include <boost/locale.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
#include <boost/math/special_functions/sign.hpp>
#include <cmath>
#include <limits>
@ -31,6 +31,7 @@
#include <thrift/protocol/TBase64Utils.h>
#include <thrift/transport/TTransportException.h>
#include <thrift/TToString.h>
using namespace apache::thrift::transport;
@ -397,7 +398,7 @@ private:
bool first_;
};
TJSONProtocol::TJSONProtocol(boost::shared_ptr<TTransport> ptrans)
TJSONProtocol::TJSONProtocol(stdcxx::shared_ptr<TTransport> ptrans)
: TVirtualProtocol<TJSONProtocol>(ptrans),
trans_(ptrans.get()),
context_(new TJSONContext()),
@ -407,7 +408,7 @@ TJSONProtocol::TJSONProtocol(boost::shared_ptr<TTransport> ptrans)
TJSONProtocol::~TJSONProtocol() {
}
void TJSONProtocol::pushContext(boost::shared_ptr<TJSONContext> c) {
void TJSONProtocol::pushContext(stdcxx::shared_ptr<TJSONContext> c) {
contexts_.push(context_);
context_ = c;
}
@ -503,7 +504,7 @@ uint32_t TJSONProtocol::writeJSONBase64(const std::string& str) {
template <typename NumberType>
uint32_t TJSONProtocol::writeJSONInteger(NumberType num) {
uint32_t result = context_->write(*trans_);
std::string val(boost::lexical_cast<std::string>(num));
std::string val(to_string(num));
bool escapeNum = context_->escapeNum();
if (escapeNum) {
trans_->write(&kJSONStringDelimiter, 1);
@ -524,7 +525,7 @@ namespace {
std::string doubleToString(double d) {
std::ostringstream str;
str.imbue(std::locale::classic());
const int max_digits10 = 2 + std::numeric_limits<double>::digits10;
const std::streamsize max_digits10 = 2 + std::numeric_limits<double>::digits10;
str.precision(max_digits10);
str << d;
return str.str();
@ -575,7 +576,7 @@ uint32_t TJSONProtocol::writeJSONDouble(double num) {
uint32_t TJSONProtocol::writeJSONObjectStart() {
uint32_t result = context_->write(*trans_);
trans_->write(&kJSONObjectStart, 1);
pushContext(boost::shared_ptr<TJSONContext>(new JSONPairContext()));
pushContext(stdcxx::shared_ptr<TJSONContext>(new JSONPairContext()));
return result + 1;
}
@ -588,7 +589,7 @@ uint32_t TJSONProtocol::writeJSONObjectEnd() {
uint32_t TJSONProtocol::writeJSONArrayStart() {
uint32_t result = context_->write(*trans_);
trans_->write(&kJSONArrayStart, 1);
pushContext(boost::shared_ptr<TJSONContext>(new JSONListContext()));
pushContext(stdcxx::shared_ptr<TJSONContext>(new JSONListContext()));
return result + 1;
}
@ -684,7 +685,7 @@ uint32_t TJSONProtocol::writeBool(const bool value) {
}
uint32_t TJSONProtocol::writeByte(const int8_t byte) {
// writeByte() must be handled specially because boost::lexical cast sees
// writeByte() must be handled specially because to_string sees
// int8_t as a text type instead of an integer type
return writeJSONInteger((int16_t)byte);
}
@ -772,7 +773,7 @@ uint32_t TJSONProtocol::readJSONString(std::string& str, bool skipContext) {
continue;
} else {
size_t pos = kEscapeChars.find(ch);
if (pos == std::string::npos) {
if (pos == kEscapeChars.npos) {
throw TProtocolException(TProtocolException::INVALID_DATA,
"Expected control char, got '" + std::string((const char*)&ch, 1)
+ "'.");
@ -842,6 +843,19 @@ uint32_t TJSONProtocol::readJSONNumericChars(std::string& str) {
return result;
}
namespace {
template <typename T>
T fromString(const std::string& s) {
T t;
std::istringstream str(s);
str.imbue(std::locale::classic());
str >> t;
if (str.bad() || !str.eof())
throw std::runtime_error(s);
return t;
}
}
// Reads a sequence of characters and assembles them into a number,
// returning them via num
template <typename NumberType>
@ -853,10 +867,10 @@ uint32_t TJSONProtocol::readJSONInteger(NumberType& num) {
std::string str;
result += readJSONNumericChars(str);
try {
num = boost::lexical_cast<NumberType>(str);
} catch (boost::bad_lexical_cast e) {
num = fromString<NumberType>(str);
} catch (const std::runtime_error&) {
throw TProtocolException(TProtocolException::INVALID_DATA,
"Expected numeric value; got \"" + str + "\"");
"Expected numeric value; got \"" + str + "\"");
}
if (context_->escapeNum()) {
result += readJSONSyntaxChar(kJSONStringDelimiter);
@ -864,18 +878,6 @@ uint32_t TJSONProtocol::readJSONInteger(NumberType& num) {
return result;
}
namespace {
double stringToDouble(const std::string& s) {
double d;
std::istringstream str(s);
str.imbue(std::locale::classic());
str >> d;
if (str.bad() || !str.eof())
throw std::runtime_error(s);
return d;
}
}
// Reads a JSON number or string and interprets it as a double.
uint32_t TJSONProtocol::readJSONDouble(double& num) {
uint32_t result = context_->read(reader_);
@ -896,7 +898,7 @@ uint32_t TJSONProtocol::readJSONDouble(double& num) {
"Numeric data unexpectedly quoted");
}
try {
num = stringToDouble(str);
num = fromString<double>(str);
} catch (std::runtime_error e) {
throw TProtocolException(TProtocolException::INVALID_DATA,
"Expected numeric value; got \"" + str + "\"");
@ -909,7 +911,7 @@ uint32_t TJSONProtocol::readJSONDouble(double& num) {
}
result += readJSONNumericChars(str);
try {
num = stringToDouble(str);
num = fromString<double>(str);
} catch (std::runtime_error e) {
throw TProtocolException(TProtocolException::INVALID_DATA,
"Expected numeric value; got \"" + str + "\"");
@ -921,7 +923,7 @@ uint32_t TJSONProtocol::readJSONDouble(double& num) {
uint32_t TJSONProtocol::readJSONObjectStart() {
uint32_t result = context_->read(reader_);
result += readJSONSyntaxChar(kJSONObjectStart);
pushContext(boost::shared_ptr<TJSONContext>(new JSONPairContext()));
pushContext(stdcxx::shared_ptr<TJSONContext>(new JSONPairContext()));
return result;
}
@ -934,7 +936,7 @@ uint32_t TJSONProtocol::readJSONObjectEnd() {
uint32_t TJSONProtocol::readJSONArrayStart() {
uint32_t result = context_->read(reader_);
result += readJSONSyntaxChar(kJSONArrayStart);
pushContext(boost::shared_ptr<TJSONContext>(new JSONListContext()));
pushContext(stdcxx::shared_ptr<TJSONContext>(new JSONListContext()));
return result;
}

View file

@ -87,20 +87,21 @@ class TJSONContext;
* 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.
* yet verified whether std::istringstream::operator>>, 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(stdcxx::shared_ptr<TTransport> ptrans);
~TJSONProtocol();
private:
void pushContext(boost::shared_ptr<TJSONContext> c);
void pushContext(stdcxx::shared_ptr<TJSONContext> c);
void popContext();
@ -275,8 +276,8 @@ public:
private:
TTransport* trans_;
std::stack<boost::shared_ptr<TJSONContext> > contexts_;
boost::shared_ptr<TJSONContext> context_;
std::stack<stdcxx::shared_ptr<TJSONContext> > contexts_;
stdcxx::shared_ptr<TJSONContext> context_;
LookaheadReader reader_;
};
@ -289,8 +290,8 @@ public:
virtual ~TJSONProtocolFactory() {}
boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) {
return boost::shared_ptr<TProtocol>(new TJSONProtocol(trans));
stdcxx::shared_ptr<TProtocol> getProtocol(stdcxx::shared_ptr<TTransport> trans) {
return stdcxx::shared_ptr<TProtocol>(new TJSONProtocol(trans));
}
};
}
@ -308,7 +309,7 @@ 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);
stdcxx::shared_ptr<TTransport> trans(buffer);
TJSONProtocol protocol(trans);
ts.write(&protocol);

View file

@ -25,7 +25,7 @@
namespace apache {
namespace thrift {
namespace protocol {
using boost::shared_ptr;
using stdcxx::shared_ptr;
/**
* <code>TMultiplexedProtocol</code> is a protocol-independent concrete decorator

View file

@ -28,7 +28,7 @@
#include <thrift/transport/TTransport.h>
#include <thrift/protocol/TProtocolException.h>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
#include <boost/static_assert.hpp>
#ifdef HAVE_NETINET_IN_H
@ -550,12 +550,12 @@ public:
}
virtual uint32_t skip_virt(TType type);
inline boost::shared_ptr<TTransport> getTransport() { return ptrans_; }
inline stdcxx::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_; }
inline stdcxx::shared_ptr<TTransport> getInputTransport() { return ptrans_; }
inline stdcxx::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.
@ -577,11 +577,11 @@ public:
void setRecurisionLimit(uint32_t depth) {recursion_limit_ = depth;}
protected:
TProtocol(boost::shared_ptr<TTransport> ptrans)
TProtocol(stdcxx::shared_ptr<TTransport> ptrans)
: ptrans_(ptrans), input_recursion_depth_(0), output_recursion_depth_(0), recursion_limit_(DEFAULT_RECURSION_LIMIT)
{}
boost::shared_ptr<TTransport> ptrans_;
stdcxx::shared_ptr<TTransport> ptrans_;
private:
TProtocol() {}
@ -599,9 +599,9 @@ public:
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) {
virtual stdcxx::shared_ptr<TProtocol> getProtocol(stdcxx::shared_ptr<TTransport> trans) = 0;
virtual stdcxx::shared_ptr<TProtocol> getProtocol(stdcxx::shared_ptr<TTransport> inTrans,
stdcxx::shared_ptr<TTransport> outTrans) {
(void)outTrans;
return getProtocol(inTrans);
}
@ -672,7 +672,7 @@ uint32_t skip(Protocol_& prot, TType type) {
return prot.readBool(boolv);
}
case T_BYTE: {
int8_t bytev;
int8_t bytev = 0;
return prot.readByte(bytev);
}
case T_I16: {
@ -753,6 +753,8 @@ uint32_t skip(Protocol_& prot, TType type) {
case T_UTF8:
case T_UTF16:
break;
default:
throw TProtocolException(TProtocolException::INVALID_DATA);
}
return 0;
}

View file

@ -21,12 +21,12 @@
#define THRIFT_TPROTOCOLDECORATOR_H_ 1
#include <thrift/protocol/TProtocol.h>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
namespace protocol {
using boost::shared_ptr;
using stdcxx::shared_ptr;
/**
* <code>TProtocolDecorator</code> forwards all requests to an enclosed

View file

@ -36,7 +36,7 @@ using apache::thrift::transport::TTransport;
*/
class TProtocolTap : public TVirtualProtocol<TProtocolTap> {
public:
TProtocolTap(boost::shared_ptr<TProtocol> source, boost::shared_ptr<TProtocol> sink)
TProtocolTap(stdcxx::shared_ptr<TProtocol> source, stdcxx::shared_ptr<TProtocol> sink)
: TVirtualProtocol<TProtocolTap>(source->getTransport()), source_(source), sink_(sink) {}
uint32_t readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqid) {
@ -167,8 +167,8 @@ public:
}
private:
boost::shared_ptr<TProtocol> source_;
boost::shared_ptr<TProtocol> sink_;
stdcxx::shared_ptr<TProtocol> source_;
stdcxx::shared_ptr<TProtocol> sink_;
};
}
}

View file

@ -301,7 +301,7 @@ public:
uint32_t skip(TType type) { return ::apache::thrift::protocol::skip(*this, type); }
protected:
TProtocolDefaults(boost::shared_ptr<TTransport> ptrans) : TProtocol(ptrans) {}
TProtocolDefaults(stdcxx::shared_ptr<TTransport> ptrans) : TProtocol(ptrans) {}
};
/**
@ -504,7 +504,7 @@ public:
using Super_::readBool; // so we don't hide readBool(bool&)
protected:
TVirtualProtocol(boost::shared_ptr<TTransport> ptrans) : Super_(ptrans) {}
TVirtualProtocol(stdcxx::shared_ptr<TTransport> ptrans) : Super_(ptrans) {}
};
}
}

View file

@ -23,11 +23,13 @@
#include <QIODevice>
#include <thrift/transport/TBufferTransports.h>
using boost::shared_ptr;
#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
using stdcxx::shared_ptr;
namespace transport {
TQIODeviceTransport::TQIODeviceTransport(shared_ptr<QIODevice> dev) : dev_(dev) {

View file

@ -20,7 +20,7 @@
#ifndef _THRIFT_ASYNC_TQIODEVICE_TRANSPORT_H_
#define _THRIFT_ASYNC_TQIODEVICE_TRANSPORT_H_ 1
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
#include <thrift/transport/TVirtualTransport.h>
@ -36,7 +36,7 @@ namespace transport {
class TQIODeviceTransport
: public apache::thrift::transport::TVirtualTransport<TQIODeviceTransport> {
public:
explicit TQIODeviceTransport(boost::shared_ptr<QIODevice> dev);
explicit TQIODeviceTransport(stdcxx::shared_ptr<QIODevice> dev);
virtual ~TQIODeviceTransport();
void open();
@ -59,7 +59,7 @@ private:
TQIODeviceTransport(const TQIODeviceTransport&);
TQIODeviceTransport& operator=(const TQIODeviceTransport&);
boost::shared_ptr<QIODevice> dev_;
stdcxx::shared_ptr<QIODevice> dev_;
};
}
}

View file

@ -23,19 +23,20 @@
#include <QMetaType>
#include <QTcpSocket>
#include <thrift/cxxfunctional.h>
#include <thrift/stdcxx.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;
using apache::thrift::stdcxx::function;
using apache::thrift::stdcxx::placeholders::_1;
using apache::thrift::stdcxx::shared_ptr;
QT_USE_NAMESPACE
@ -110,7 +111,7 @@ void TQTcpServer::beginDecode() {
try {
processor_
->process(bind(&TQTcpServer::finish, this, ctx, apache::thrift::stdcxx::placeholders::_1),
->process(bind(&TQTcpServer::finish, this, ctx, _1),
ctx->iprot_,
ctx->oprot_);
} catch (const TTransportException& ex) {

View file

@ -23,7 +23,7 @@
#include <QObject>
#include <QTcpServer>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
@ -47,9 +47,9 @@ class TAsyncProcessor;
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,
TQTcpServer(stdcxx::shared_ptr<QTcpServer> server,
stdcxx::shared_ptr<TAsyncProcessor> processor,
stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory> protocolFactory,
QObject* parent = NULL);
virtual ~TQTcpServer();
@ -65,13 +65,13 @@ private:
struct ConnectionContext;
void scheduleDeleteConnectionContext(QTcpSocket* connection);
void finish(boost::shared_ptr<ConnectionContext> ctx, bool healthy);
void finish(stdcxx::shared_ptr<ConnectionContext> ctx, bool healthy);
boost::shared_ptr<QTcpServer> server_;
boost::shared_ptr<TAsyncProcessor> processor_;
boost::shared_ptr<apache::thrift::protocol::TProtocolFactory> pfact_;
stdcxx::shared_ptr<QTcpServer> server_;
stdcxx::shared_ptr<TAsyncProcessor> processor_;
stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory> pfact_;
typedef std::map<QTcpSocket*, boost::shared_ptr<ConnectionContext> > ConnectionContextMap;
typedef std::map<QTcpSocket*, stdcxx::shared_ptr<ConnectionContext> > ConnectionContextMap;
ConnectionContextMap ctxMap_;
};
}

View file

@ -28,7 +28,7 @@ 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 stdcxx::shared_ptr;
using std::string;
TConnectedClient::TConnectedClient(const shared_ptr<TProcessor>& processor,

View file

@ -20,7 +20,7 @@
#ifndef _THRIFT_SERVER_TCONNECTEDCLIENT_H_
#define _THRIFT_SERVER_TCONNECTEDCLIENT_H_ 1
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
#include <thrift/TProcessor.h>
#include <thrift/protocol/TProtocol.h>
#include <thrift/server/TServer.h>
@ -49,11 +49,11 @@ public:
* @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);
const stdcxx::shared_ptr<apache::thrift::TProcessor>& processor,
const stdcxx::shared_ptr<apache::thrift::protocol::TProtocol>& inputProtocol,
const stdcxx::shared_ptr<apache::thrift::protocol::TProtocol>& outputProtocol,
const stdcxx::shared_ptr<apache::thrift::server::TServerEventHandler>& eventHandler,
const stdcxx::shared_ptr<apache::thrift::transport::TTransport>& client);
/**
* Destructor.
@ -92,11 +92,11 @@ protected:
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_;
stdcxx::shared_ptr<apache::thrift::TProcessor> processor_;
stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> inputProtocol_;
stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> outputProtocol_;
stdcxx::shared_ptr<apache::thrift::server::TServerEventHandler> eventHandler_;
stdcxx::shared_ptr<apache::thrift::transport::TTransport> client_;
/**
* Context acquired from the eventHandler_ if one exists.

View file

@ -17,8 +17,6 @@
* under the License.
*/
#define __STDC_FORMAT_MACROS
#include <thrift/thrift-config.h>
#include <thrift/server/TNonblockingServer.h>
@ -27,9 +25,14 @@
#include <thrift/concurrency/PlatformThreadFactory.h>
#include <thrift/transport/PlatformSocket.h>
#include <algorithm>
#include <iostream>
#ifdef HAVE_SYS_SELECT_H
#ifdef HAVE_POLL_H
#include <poll.h>
#elif HAVE_SYS_POLL_H
#include <sys/poll.h>
#elif HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
@ -64,13 +67,12 @@
#define AF_LOCAL AF_UNIX
#endif
#if !defined(PRIu32)
#define PRIu32 "I32u"
#define PRIu64 "I64u"
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#if defined(_WIN32) && (_WIN32_WINNT < 0x0600)
#define AI_ADDRCONFIG 0x0400
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
namespace apache {
@ -80,10 +82,9 @@ namespace server {
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace apache::thrift::concurrency;
using namespace std;
using apache::thrift::transport::TSocket;
using apache::thrift::transport::TTransportException;
using boost::shared_ptr;
using stdcxx::shared_ptr;
/// Three states for sockets: recv frame size, recv data, and send mode
enum TSocketState { SOCKET_RECV_FRAMING, SOCKET_RECV, SOCKET_SEND };
@ -118,10 +119,10 @@ private:
TNonblockingServer* server_;
/// TProcessor
boost::shared_ptr<TProcessor> processor_;
stdcxx::shared_ptr<TProcessor> processor_;
/// Object wrapping network socket
boost::shared_ptr<TSocket> tSocket_;
stdcxx::shared_ptr<TSocket> tSocket_;
/// Libevent object
struct event event_;
@ -163,23 +164,23 @@ private:
int32_t callsForResize_;
/// Transport to read from
boost::shared_ptr<TMemoryBuffer> inputTransport_;
stdcxx::shared_ptr<TMemoryBuffer> inputTransport_;
/// Transport that processor writes to
boost::shared_ptr<TMemoryBuffer> outputTransport_;
stdcxx::shared_ptr<TMemoryBuffer> outputTransport_;
/// extra transport generated by transport factory (e.g. BufferedRouterTransport)
boost::shared_ptr<TTransport> factoryInputTransport_;
boost::shared_ptr<TTransport> factoryOutputTransport_;
stdcxx::shared_ptr<TTransport> factoryInputTransport_;
stdcxx::shared_ptr<TTransport> factoryOutputTransport_;
/// Protocol decoder
boost::shared_ptr<TProtocol> inputProtocol_;
stdcxx::shared_ptr<TProtocol> inputProtocol_;
/// Protocol encoder
boost::shared_ptr<TProtocol> outputProtocol_;
stdcxx::shared_ptr<TProtocol> outputProtocol_;
/// Server event handler, if any
boost::shared_ptr<TServerEventHandler> serverEventHandler_;
stdcxx::shared_ptr<TServerEventHandler> serverEventHandler_;
/// Thrift call context, if any
void* connectionContext_;
@ -212,10 +213,8 @@ public:
class Task;
/// Constructor
TConnection(THRIFT_SOCKET socket,
TNonblockingIOThread* ioThread,
const sockaddr* addr,
socklen_t addrLen) {
TConnection(stdcxx::shared_ptr<TSocket> socket,
TNonblockingIOThread* ioThread) {
readBuffer_ = NULL;
readBufferSize_ = 0;
@ -227,8 +226,10 @@ public:
inputTransport_.reset(new TMemoryBuffer(readBuffer_, readBufferSize_));
outputTransport_.reset(
new TMemoryBuffer(static_cast<uint32_t>(server_->getWriteBufferDefaultSize())));
tSocket_.reset(new TSocket());
init(socket, ioThread, addr, addrLen);
tSocket_ = socket;
init(ioThread);
}
~TConnection() { std::free(readBuffer_); }
@ -245,10 +246,10 @@ public:
void checkIdleBufferMemLimit(size_t readLimit, size_t writeLimit);
/// Initialize
void init(THRIFT_SOCKET socket,
TNonblockingIOThread* ioThread,
const sockaddr* addr,
socklen_t addrLen);
void init(TNonblockingIOThread* ioThread);
/// set socket for connection
void setSocket(stdcxx::shared_ptr<TSocket> socket);
/**
* This is called when the application transitions from one state into
@ -291,6 +292,7 @@ public:
void forceClose() {
appState_ = APP_CLOSE_CONNECTION;
if (!notifyIOThread()) {
server_->decrementActiveProcessors();
close();
throw TException("TConnection::forceClose: failed write on notify pipe");
}
@ -303,10 +305,10 @@ public:
TAppState getState() const { return appState_; }
/// return the TSocket transport wrapping this network connection
boost::shared_ptr<TSocket> getTSocket() const { return tSocket_; }
stdcxx::shared_ptr<TSocket> getTSocket() const { return tSocket_; }
/// return the server event handler if any
boost::shared_ptr<TServerEventHandler> getServerEventHandler() { return serverEventHandler_; }
stdcxx::shared_ptr<TServerEventHandler> getServerEventHandler() { return serverEventHandler_; }
/// return the Thrift connection context if any
void* getConnectionContext() { return connectionContext_; }
@ -314,9 +316,9 @@ public:
class TNonblockingServer::TConnection::Task : public Runnable {
public:
Task(boost::shared_ptr<TProcessor> processor,
boost::shared_ptr<TProtocol> input,
boost::shared_ptr<TProtocol> output,
Task(stdcxx::shared_ptr<TProcessor> processor,
stdcxx::shared_ptr<TProtocol> input,
stdcxx::shared_ptr<TProtocol> output,
TConnection* connection)
: processor_(processor),
input_(input),
@ -338,7 +340,7 @@ public:
}
} catch (const TTransportException& ttx) {
GlobalOutput.printf("TNonblockingServer: client died: %s", ttx.what());
} catch (const bad_alloc&) {
} catch (const std::bad_alloc&) {
GlobalOutput("TNonblockingServer: caught bad_alloc exception.");
exit(1);
} catch (const std::exception& x) {
@ -352,6 +354,7 @@ public:
// Signal completion back to the libevent thread via a pipe
if (!connection_->notifyIOThread()) {
GlobalOutput.printf("TNonblockingServer: failed to notifyIOThread, closing.");
connection_->server_->decrementActiveProcessors();
connection_->close();
throw TException("TNonblockingServer::Task::run: failed write on notify pipe");
}
@ -360,21 +363,15 @@ public:
TConnection* getTConnection() { return connection_; }
private:
boost::shared_ptr<TProcessor> processor_;
boost::shared_ptr<TProtocol> input_;
boost::shared_ptr<TProtocol> output_;
stdcxx::shared_ptr<TProcessor> processor_;
stdcxx::shared_ptr<TProtocol> input_;
stdcxx::shared_ptr<TProtocol> output_;
TConnection* connection_;
boost::shared_ptr<TServerEventHandler> serverEventHandler_;
stdcxx::shared_ptr<TServerEventHandler> serverEventHandler_;
void* connectionContext_;
};
void TNonblockingServer::TConnection::init(THRIFT_SOCKET socket,
TNonblockingIOThread* ioThread,
const sockaddr* addr,
socklen_t addrLen) {
tSocket_->setSocketFD(socket);
tSocket_->setCachedAddress(addr, addrLen);
void TNonblockingServer::TConnection::init(TNonblockingIOThread* ioThread) {
ioThread_ = ioThread;
server_ = ioThread->getServer();
appState_ = APP_INIT;
@ -417,6 +414,10 @@ void TNonblockingServer::TConnection::init(THRIFT_SOCKET socket,
processor_ = server_->getProcessor(inputProtocol_, outputProtocol_, tSocket_);
}
void TNonblockingServer::TConnection::setSocket(stdcxx::shared_ptr<TSocket> socket) {
tSocket_ = socket;
}
void TNonblockingServer::TConnection::workSocket() {
int got = 0, left = 0, sent = 0;
uint32_t fetch = 0;
@ -442,10 +443,14 @@ void TNonblockingServer::TConnection::workSocket() {
}
readBufferPos_ += fetch;
} catch (TTransportException& te) {
GlobalOutput.printf("TConnection::workSocket(): %s", te.what());
close();
//In Nonblocking SSLSocket some operations need to be retried again.
//Current approach is parsing exception message, but a better solution needs to be investigated.
if(!strstr(te.what(), "retry")) {
GlobalOutput.printf("TConnection::workSocket(): %s", te.what());
close();
return;
return;
}
}
if (readBufferPos_ < sizeof(framing.size)) {
@ -471,6 +476,18 @@ void TNonblockingServer::TConnection::workSocket() {
}
// size known; now get the rest of the frame
transition();
// If the socket has more data than the frame header, continue to work on it. This is not strictly necessary for
// regular sockets, because if there is more data, libevent will fire the event handler registered for read
// readiness, which will in turn call workSocket(). However, some socket types (such as TSSLSocket) may have the
// data sitting in their internal buffers and from libevent's perspective, there is no further data available. In
// that case, not having this workSocket() call here would result in a hang as we will never get to work the socket,
// despite having more data.
if (tSocket_->hasPendingDataToRead())
{
workSocket();
}
return;
case SOCKET_RECV:
@ -482,8 +499,12 @@ void TNonblockingServer::TConnection::workSocket() {
fetch = readWant_ - readBufferPos_;
got = tSocket_->read(readBuffer_ + readBufferPos_, fetch);
} catch (TTransportException& te) {
GlobalOutput.printf("TConnection::workSocket(): %s", te.what());
close();
//In Nonblocking SSLSocket some operations need to be retried again.
//Current approach is parsing exception message, but a better solution needs to be investigated.
if(!strstr(te.what(), "retry")) {
GlobalOutput.printf("TConnection::workSocket(): %s", te.what());
close();
}
return;
}
@ -513,7 +534,7 @@ void TNonblockingServer::TConnection::workSocket() {
// If there is no data to send, then let us move on
if (writeBufferPos_ == writeBufferSize_) {
GlobalOutput("WARNING: Send state with no data to send\n");
GlobalOutput("WARNING: Send state with no data to send");
transition();
return;
}
@ -589,26 +610,29 @@ void TNonblockingServer::TConnection::transition() {
// We are setting up a Task to do this work and we will wait on it
// Create task and dispatch to the thread manager
boost::shared_ptr<Runnable> task = boost::shared_ptr<Runnable>(
stdcxx::shared_ptr<Runnable> task = stdcxx::shared_ptr<Runnable>(
new Task(processor_, inputProtocol_, outputProtocol_, this));
// The application is now waiting on the task to finish
appState_ = APP_WAIT_TASK;
// Set this connection idle so that libevent doesn't process more
// data on it while we're still waiting for the threadmanager to
// finish this task
setIdle();
try {
server_->addTask(task);
} catch (IllegalStateException& ise) {
// The ThreadManager is not ready to handle any more tasks (it's probably shutting down).
GlobalOutput.printf("IllegalStateException: Server::process() %s", ise.what());
server_->decrementActiveProcessors();
close();
} catch (TimedOutException& to) {
GlobalOutput.printf("[ERROR] TimedOutException: Server::process() %s", to.what());
server_->decrementActiveProcessors();
close();
}
// Set this connection idle so that libevent doesn't process more
// data on it while we're still waiting for the threadmanager to
// finish this task
setIdle();
return;
} else {
try {
@ -639,6 +663,7 @@ void TNonblockingServer::TConnection::transition() {
return;
}
}
// fallthrough
// Intentionally fall through here, the call to process has written into
// the writeBuffer_
@ -669,9 +694,6 @@ void TNonblockingServer::TConnection::transition() {
appState_ = APP_SEND_RESULT;
setWrite();
// Try to work the socket immediately
// workSocket();
return;
}
@ -690,6 +712,7 @@ void TNonblockingServer::TConnection::transition() {
server_->getIdleWriteBufferLimit());
callsForResize_ = 0;
}
// fallthrough
// N.B.: We also intentionally fall through here into the INIT state!
@ -710,9 +733,6 @@ void TNonblockingServer::TConnection::transition() {
// Register read event
setRead();
// Try to work the socket right away
// workSocket();
return;
case APP_READ_FRAME_SIZE:
@ -745,9 +765,6 @@ void TNonblockingServer::TConnection::transition() {
socketState_ = SOCKET_RECV;
appState_ = APP_READ_REQUEST;
// Work the socket right away
// workSocket();
return;
case APP_CLOSE_CONNECTION:
@ -768,11 +785,9 @@ void TNonblockingServer::TConnection::setFlags(short eventFlags) {
}
// Delete a previously existing event
if (eventFlags_ != 0) {
if (event_del(&event_) == -1) {
GlobalOutput("TConnection::setFlags event_del");
return;
}
if (eventFlags_ && event_del(&event_) == -1) {
GlobalOutput.perror("TConnection::setFlags() event_del", THRIFT_GET_SOCKET_ERROR);
return;
}
// Update in memory structure
@ -815,7 +830,7 @@ void TNonblockingServer::TConnection::setFlags(short eventFlags) {
// Add the event
if (event_add(&event_, 0) == -1) {
GlobalOutput("TConnection::setFlags(): could not event_add");
GlobalOutput.perror("TConnection::setFlags(): could not event_add", THRIFT_GET_SOCKET_ERROR);
}
}
@ -823,10 +838,7 @@ void TNonblockingServer::TConnection::setFlags(short eventFlags) {
* Closes a connection
*/
void TNonblockingServer::TConnection::close() {
// Delete the registered libevent
if (event_del(&event_) == -1) {
GlobalOutput.perror("TConnection::close() event_del", THRIFT_GET_SOCKET_ERROR);
}
setIdle();
if (serverEventHandler_) {
serverEventHandler_->deleteContext(connectionContext_, inputProtocol_, outputProtocol_);
@ -876,9 +888,9 @@ TNonblockingServer::~TNonblockingServer() {
// objects and the Thread objects have shared_ptrs to the TNonblockingIOThread
// objects (as runnable) so these objects will never deallocate without help.
while (!ioThreads_.empty()) {
boost::shared_ptr<TNonblockingIOThread> iot = ioThreads_.back();
stdcxx::shared_ptr<TNonblockingIOThread> iot = ioThreads_.back();
ioThreads_.pop_back();
iot->setThread(boost::shared_ptr<Thread>());
iot->setThread(stdcxx::shared_ptr<Thread>());
}
}
@ -886,9 +898,7 @@ TNonblockingServer::~TNonblockingServer() {
* Creates a new connection either by reusing an object off the stack or
* by allocating a new one entirely
*/
TNonblockingServer::TConnection* TNonblockingServer::createConnection(THRIFT_SOCKET socket,
const sockaddr* addr,
socklen_t addrLen) {
TNonblockingServer::TConnection* TNonblockingServer::createConnection(stdcxx::shared_ptr<TSocket> socket) {
// Check the stack
Guard g(connMutex_);
@ -902,12 +912,13 @@ TNonblockingServer::TConnection* TNonblockingServer::createConnection(THRIFT_SOC
// Check the connection stack to see if we can re-use
TConnection* result = NULL;
if (connectionStack_.empty()) {
result = new TConnection(socket, ioThread, addr, addrLen);
result = new TConnection(socket, ioThread);
++numTConnections_;
} else {
result = connectionStack_.top();
connectionStack_.pop();
result->init(socket, ioThread, addr, addrLen);
result->setSocket(socket);
result->init(ioThread);
}
activeConnections_.push_back(result);
return result;
@ -942,53 +953,35 @@ void TNonblockingServer::handleEvent(THRIFT_SOCKET fd, short which) {
// Make sure that libevent didn't mess up the socket handles
assert(fd == serverSocket_);
// Server socket accepted a new connection
socklen_t addrLen;
sockaddr_storage addrStorage;
sockaddr* addrp = (sockaddr*)&addrStorage;
addrLen = sizeof(addrStorage);
// Going to accept a new client socket
THRIFT_SOCKET clientSocket;
stdcxx::shared_ptr<TSocket> clientSocket;
// Accept as many new clients as possible, even though libevent signaled only
// one, this helps us to avoid having to go back into the libevent engine so
// many times
while ((clientSocket = ::accept(fd, addrp, &addrLen)) != -1) {
clientSocket = serverTransport_->accept();
if (clientSocket) {
// If we're overloaded, take action here
if (overloadAction_ != T_OVERLOAD_NO_ACTION && serverOverloaded()) {
Guard g(connMutex_);
nConnectionsDropped_++;
nTotalConnectionsDropped_++;
if (overloadAction_ == T_OVERLOAD_CLOSE_ON_ACCEPT) {
::THRIFT_CLOSESOCKET(clientSocket);
clientSocket->close();
return;
} else if (overloadAction_ == T_OVERLOAD_DRAIN_TASK_QUEUE) {
if (!drainPendingTask()) {
// Nothing left to discard, so we drop connection instead.
::THRIFT_CLOSESOCKET(clientSocket);
clientSocket->close();
return;
}
}
}
// Explicitly set this socket to NONBLOCK mode
int flags;
if ((flags = THRIFT_FCNTL(clientSocket, THRIFT_F_GETFL, 0)) < 0
|| THRIFT_FCNTL(clientSocket, THRIFT_F_SETFL, flags | THRIFT_O_NONBLOCK) < 0) {
GlobalOutput.perror("thriftServerEventHandler: set THRIFT_O_NONBLOCK (THRIFT_FCNTL) ",
THRIFT_GET_SOCKET_ERROR);
::THRIFT_CLOSESOCKET(clientSocket);
return;
}
// Create a new TConnection for this client socket.
TConnection* clientConnection = createConnection(clientSocket, addrp, addrLen);
TConnection* clientConnection = createConnection(clientSocket);
// Fail fast if we could not create a TConnection object
if (clientConnection == NULL) {
GlobalOutput.printf("thriftServerEventHandler: failed TConnection factory");
::THRIFT_CLOSESOCKET(clientSocket);
clientSocket->close();
return;
}
@ -1009,18 +1002,9 @@ void TNonblockingServer::handleEvent(THRIFT_SOCKET fd, short which) {
} else {
if (!clientConnection->notifyIOThread()) {
GlobalOutput.perror("[ERROR] notifyIOThread failed on fresh connection, closing", errno);
returnConnection(clientConnection);
clientConnection->close();
}
}
// addrLen is written by the accept() call, so needs to be set before the next call.
addrLen = sizeof(addrStorage);
}
// Done looping accept, now we have to make sure the error is due to
// blocking. Any other error is a problem
if (THRIFT_GET_SOCKET_ERROR != THRIFT_EAGAIN && THRIFT_GET_SOCKET_ERROR != THRIFT_EWOULDBLOCK) {
GlobalOutput.perror("thriftServerEventHandler: accept() ", THRIFT_GET_SOCKET_ERROR);
}
}
@ -1028,132 +1012,12 @@ void TNonblockingServer::handleEvent(THRIFT_SOCKET fd, short which) {
* Creates a socket to listen on and binds it to the local port.
*/
void TNonblockingServer::createAndListenOnSocket() {
#ifdef _WIN32
TWinsockSingleton::create();
#endif // _WIN32
THRIFT_SOCKET s;
struct addrinfo hints, *res, *res0;
int error;
char port[sizeof("65536") + 1];
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
sprintf(port, "%d", port_);
// Wildcard address
error = getaddrinfo(NULL, port, &hints, &res0);
if (error) {
throw TException("TNonblockingServer::serve() getaddrinfo "
+ string(THRIFT_GAI_STRERROR(error)));
}
// Pick the ipv6 address first since ipv4 addresses can be mapped
// into ipv6 space.
for (res = res0; res; res = res->ai_next) {
if (res->ai_family == AF_INET6 || res->ai_next == NULL)
break;
}
// Create the server socket
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (s == -1) {
freeaddrinfo(res0);
throw TException("TNonblockingServer::serve() socket() -1");
}
#ifdef IPV6_V6ONLY
if (res->ai_family == AF_INET6) {
int zero = 0;
if (-1 == setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, const_cast_sockopt(&zero), sizeof(zero))) {
GlobalOutput("TServerSocket::listen() IPV6_V6ONLY");
}
}
#endif // #ifdef IPV6_V6ONLY
int one = 1;
// Set THRIFT_NO_SOCKET_CACHING to avoid 2MSL delay on server restart
setsockopt(s, SOL_SOCKET, THRIFT_NO_SOCKET_CACHING, const_cast_sockopt(&one), sizeof(one));
if (::bind(s, res->ai_addr, static_cast<int>(res->ai_addrlen)) == -1) {
::THRIFT_CLOSESOCKET(s);
freeaddrinfo(res0);
throw TTransportException(TTransportException::NOT_OPEN,
"TNonblockingServer::serve() bind",
THRIFT_GET_SOCKET_ERROR);
}
// Done with the addr info
freeaddrinfo(res0);
// Set up this file descriptor for listening
listenSocket(s);
serverTransport_->listen();
serverSocket_ = serverTransport_->getSocketFD();
}
/**
* Takes a socket created by listenSocket() and sets various options on it
* to prepare for use in the server.
*/
void TNonblockingServer::listenSocket(THRIFT_SOCKET s) {
// Set socket to nonblocking mode
int flags;
if ((flags = THRIFT_FCNTL(s, THRIFT_F_GETFL, 0)) < 0
|| THRIFT_FCNTL(s, THRIFT_F_SETFL, flags | THRIFT_O_NONBLOCK) < 0) {
::THRIFT_CLOSESOCKET(s);
throw TException("TNonblockingServer::serve() THRIFT_O_NONBLOCK");
}
int one = 1;
struct linger ling = {0, 0};
// Keepalive to ensure full result flushing
setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, const_cast_sockopt(&one), sizeof(one));
// Turn linger off to avoid hung sockets
setsockopt(s, SOL_SOCKET, SO_LINGER, const_cast_sockopt(&ling), sizeof(ling));
// Set TCP nodelay if available, MAC OS X Hack
// See http://lists.danga.com/pipermail/memcached/2005-March/001240.html
#ifndef TCP_NOPUSH
setsockopt(s, IPPROTO_TCP, TCP_NODELAY, const_cast_sockopt(&one), sizeof(one));
#endif
#ifdef TCP_LOW_MIN_RTO
if (TSocket::getUseLowMinRto()) {
setsockopt(s, IPPROTO_TCP, TCP_LOW_MIN_RTO, const_cast_sockopt(&one), sizeof(one));
}
#endif
if (listen(s, LISTEN_BACKLOG) == -1) {
::THRIFT_CLOSESOCKET(s);
throw TTransportException(TTransportException::NOT_OPEN, "TNonblockingServer::serve() listen");
}
// Cool, this socket is good to go, set it as the serverSocket_
serverSocket_ = s;
if (!port_) {
struct sockaddr_storage addr;
socklen_t size = sizeof(addr);
if (!getsockname(serverSocket_, reinterpret_cast<sockaddr*>(&addr), &size)) {
if (addr.ss_family == AF_INET6) {
const struct sockaddr_in6* sin = reinterpret_cast<const struct sockaddr_in6*>(&addr);
listenPort_ = ntohs(sin->sin6_port);
} else {
const struct sockaddr_in* sin = reinterpret_cast<const struct sockaddr_in*>(&addr);
listenPort_ = ntohs(sin->sin_port);
}
} else {
GlobalOutput.perror("TNonblocking: failed to get listen port: ", THRIFT_GET_SOCKET_ERROR);
}
}
}
void TNonblockingServer::setThreadManager(boost::shared_ptr<ThreadManager> threadManager) {
void TNonblockingServer::setThreadManager(stdcxx::shared_ptr<ThreadManager> threadManager) {
threadManager_ = threadManager;
if (threadManager) {
threadManager->setExpireCallback(
@ -1191,7 +1055,7 @@ bool TNonblockingServer::serverOverloaded() {
bool TNonblockingServer::drainPendingTask() {
if (threadManager_) {
boost::shared_ptr<Runnable> task = threadManager_->removeNextPending();
stdcxx::shared_ptr<Runnable> task = threadManager_->removeNextPending();
if (task) {
TConnection* connection = static_cast<TConnection::Task*>(task.get())->getTConnection();
assert(connection && connection->getServer() && connection->getState() == APP_WAIT_TASK);
@ -1202,16 +1066,13 @@ bool TNonblockingServer::drainPendingTask() {
return false;
}
void TNonblockingServer::expireClose(boost::shared_ptr<Runnable> task) {
void TNonblockingServer::expireClose(stdcxx::shared_ptr<Runnable> task) {
TConnection* connection = static_cast<TConnection::Task*>(task.get())->getTConnection();
assert(connection && connection->getServer() && connection->getState() == APP_WAIT_TASK);
connection->forceClose();
}
void TNonblockingServer::stop() {
if (!port_) {
listenPort_ = 0;
}
// Breaks the event loop in all threads so that they end ASAP.
for (uint32_t i = 0; i < ioThreads_.size(); ++i) {
ioThreads_[i]->stop();
@ -1252,8 +1113,7 @@ void TNonblockingServer::registerEvents(event_base* user_event_base) {
assert(ioThreads_.size() == numIOThreads_);
assert(ioThreads_.size() > 0);
GlobalOutput.printf("TNonblockingServer: Serving on port %d, %d io threads.",
listenPort_,
GlobalOutput.printf("TNonblockingServer: Serving with %d io threads.",
ioThreads_.size());
// Launch all the secondary IO threads in separate threads
@ -1324,7 +1184,7 @@ TNonblockingIOThread::~TNonblockingIOThread() {
ownEventBase_ = false;
}
if (listenSocket_ >= 0) {
if (listenSocket_ != THRIFT_INVALID_SOCKET) {
if (0 != ::THRIFT_CLOSESOCKET(listenSocket_)) {
GlobalOutput.perror("TNonblockingIOThread listenSocket_ close(): ", THRIFT_GET_SOCKET_ERROR);
}
@ -1390,7 +1250,7 @@ void TNonblockingIOThread::registerEvents() {
event_base_get_method(eventBase_));
}
if (listenSocket_ >= 0) {
if (listenSocket_ != THRIFT_INVALID_SOCKET) {
// Register the server event
event_set(&serverEvent_,
listenSocket_,
@ -1435,10 +1295,44 @@ bool TNonblockingIOThread::notify(TNonblockingServer::TConnection* conn) {
return false;
}
fd_set wfds, efds;
long ret = -1;
int ret = -1;
long kSize = sizeof(conn);
const char* pos = reinterpret_cast<const char*>(&conn);
const char * pos = (const char *)const_cast_sockopt(&conn);
#if defined(HAVE_POLL_H) || defined(HAVE_SYS_POLL_H)
struct pollfd pfd = {fd, POLLOUT, 0};
while (kSize > 0) {
pfd.revents = 0;
ret = poll(&pfd, 1, -1);
if (ret < 0) {
return false;
} else if (ret == 0) {
continue;
}
if (pfd.revents & POLLHUP || pfd.revents & POLLERR) {
::THRIFT_CLOSESOCKET(fd);
return false;
}
if (pfd.revents & POLLOUT) {
ret = send(fd, pos, kSize, 0);
if (ret < 0) {
if (errno == EAGAIN) {
continue;
}
::THRIFT_CLOSESOCKET(fd);
return false;
}
kSize -= ret;
pos += ret;
}
}
#else
fd_set wfds, efds;
while (kSize > 0) {
FD_ZERO(&wfds);
@ -1472,6 +1366,7 @@ bool TNonblockingIOThread::notify(TNonblockingServer::TConnection* conn) {
pos += ret;
}
}
#endif
return true;
}
@ -1489,6 +1384,7 @@ void TNonblockingIOThread::notifyHandler(evutil_socket_t fd, short which, void*
if (nBytes == kSize) {
if (connection == NULL) {
// this is the command to stop our thread, exit the handler!
ioThread->breakLoop(false);
return;
}
connection->transition();
@ -1499,6 +1395,7 @@ void TNonblockingIOThread::notifyHandler(evutil_socket_t fd, short which, void*
return;
} else if (nBytes == 0) {
GlobalOutput.printf("notifyHandler: Notify socket closed!");
ioThread->breakLoop(false);
// exit the loop
break;
} else { // nBytes < 0
@ -1523,19 +1420,15 @@ void TNonblockingIOThread::breakLoop(bool error) {
::abort();
}
// sets a flag so that the loop exits on the next event
event_base_loopbreak(eventBase_);
// event_base_loopbreak() only causes the loop to exit the next time
// it wakes up. We need to force it to wake up, in case there are
// no real events it needs to process.
//
// If we're running in the same thread, we can't use the notify(0)
// mechanism to stop the thread, but happily if we're running in the
// same thread, this means the thread can't be blocking in the event
// loop either.
if (!Thread::is_current(threadId_)) {
notify(NULL);
} else {
// cause the loop to stop ASAP - even if it has things to do in it
event_base_loopbreak(eventBase_);
}
}
@ -1569,31 +1462,33 @@ void TNonblockingIOThread::setCurrentThreadHighPriority(bool value) {
}
void TNonblockingIOThread::run() {
if (eventBase_ == NULL)
if (eventBase_ == NULL) {
registerEvents();
GlobalOutput.printf("TNonblockingServer: IO thread #%d entering loop...", number_);
}
if (useHighPriority_) {
setCurrentThreadHighPriority(true);
}
// Run libevent engine, never returns, invokes calls to eventHandler
event_base_loop(eventBase_, 0);
if (eventBase_ != NULL)
{
GlobalOutput.printf("TNonblockingServer: IO thread #%d entering loop...", number_);
// Run libevent engine, never returns, invokes calls to eventHandler
event_base_loop(eventBase_, 0);
if (useHighPriority_) {
setCurrentThreadHighPriority(false);
if (useHighPriority_) {
setCurrentThreadHighPriority(false);
}
// cleans up our registered events
cleanupEvents();
}
// cleans up our registered events
cleanupEvents();
GlobalOutput.printf("TNonblockingServer: IO thread #%d run() done!", number_);
}
void TNonblockingIOThread::cleanupEvents() {
// stop the listen socket, if any
if (listenSocket_ >= 0) {
if (listenSocket_ != THRIFT_INVALID_SOCKET) {
if (event_del(&serverEvent_) == -1) {
GlobalOutput.perror("TNonblockingIOThread::stop() event_del: ", THRIFT_GET_SOCKET_ERROR);
}

View file

@ -21,10 +21,12 @@
#define _THRIFT_SERVER_TNONBLOCKINGSERVER_H_ 1
#include <thrift/Thrift.h>
#include <thrift/stdcxx.h>
#include <thrift/server/TServer.h>
#include <thrift/transport/PlatformSocket.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TNonblockingServerTransport.h>
#include <thrift/concurrency/ThreadManager.h>
#include <climits>
#include <thrift/concurrency/Thread.h>
@ -47,6 +49,7 @@ namespace server {
using apache::thrift::transport::TMemoryBuffer;
using apache::thrift::transport::TSocket;
using apache::thrift::transport::TNonblockingServerTransport;
using apache::thrift::protocol::TProtocol;
using apache::thrift::concurrency::Runnable;
using apache::thrift::concurrency::ThreadManager;
@ -96,10 +99,6 @@ inline SOCKOPT_CAST_T* cast_sockopt(T* v) {
* 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.
@ -157,26 +156,20 @@ private:
/// 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_;
stdcxx::shared_ptr<ThreadManager> threadManager_;
/// Is thread pool processing?
bool threadPoolProcessing_;
// Factory to create the IO threads
boost::shared_ptr<PlatformThreadFactory> ioThreadFactory_;
stdcxx::shared_ptr<PlatformThreadFactory> ioThreadFactory_;
// Vector of IOThread objects that will handle our IO
std::vector<boost::shared_ptr<TNonblockingIOThread> > ioThreads_;
std::vector<stdcxx::shared_ptr<TNonblockingIOThread> > ioThreads_;
// Index of next IO Thread to be used (for round-robin)
uint32_t nextIOThread_;
@ -269,23 +262,24 @@ private:
*/
std::vector<TConnection*> activeConnections_;
/*
*/
stdcxx::shared_ptr<TNonblockingServerTransport> serverTransport_;
/**
* 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) {
void init() {
serverSocket_ = THRIFT_INVALID_SOCKET;
numIOThreads_ = DEFAULT_IO_THREADS;
nextIOThread_ = 0;
useHighPriorityIOThreads_ = false;
port_ = port;
listenPort_ = port;
userEventBase_ = NULL;
threadPoolProcessing_ = false;
numTConnections_ = 0;
@ -307,55 +301,55 @@ private:
}
public:
TNonblockingServer(const boost::shared_ptr<TProcessorFactory>& processorFactory, int port)
: TServer(processorFactory) {
init(port);
TNonblockingServer(const stdcxx::shared_ptr<TProcessorFactory>& processorFactory,
const stdcxx::shared_ptr<apache::thrift::transport::TNonblockingServerTransport>& serverTransport)
: TServer(processorFactory), serverTransport_(serverTransport) {
init();
}
TNonblockingServer(const boost::shared_ptr<TProcessor>& processor, int port)
: TServer(processor) {
init(port);
TNonblockingServer(const stdcxx::shared_ptr<TProcessor>& processor,
const stdcxx::shared_ptr<apache::thrift::transport::TNonblockingServerTransport>& serverTransport)
: TServer(processor), serverTransport_(serverTransport) {
init();
}
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);
TNonblockingServer(const stdcxx::shared_ptr<TProcessorFactory>& processorFactory,
const stdcxx::shared_ptr<TProtocolFactory>& protocolFactory,
const stdcxx::shared_ptr<apache::thrift::transport::TNonblockingServerTransport>& serverTransport,
const stdcxx::shared_ptr<ThreadManager>& threadManager
= stdcxx::shared_ptr<ThreadManager>())
: TServer(processorFactory), serverTransport_(serverTransport) {
init();
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);
TNonblockingServer(const stdcxx::shared_ptr<TProcessor>& processor,
const stdcxx::shared_ptr<TProtocolFactory>& protocolFactory,
const stdcxx::shared_ptr<apache::thrift::transport::TNonblockingServerTransport>& serverTransport,
const stdcxx::shared_ptr<ThreadManager>& threadManager
= stdcxx::shared_ptr<ThreadManager>())
: TServer(processor), serverTransport_(serverTransport) {
init();
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);
TNonblockingServer(const stdcxx::shared_ptr<TProcessorFactory>& processorFactory,
const stdcxx::shared_ptr<TTransportFactory>& inputTransportFactory,
const stdcxx::shared_ptr<TTransportFactory>& outputTransportFactory,
const stdcxx::shared_ptr<TProtocolFactory>& inputProtocolFactory,
const stdcxx::shared_ptr<TProtocolFactory>& outputProtocolFactory,
const stdcxx::shared_ptr<apache::thrift::transport::TNonblockingServerTransport>& serverTransport,
const stdcxx::shared_ptr<ThreadManager>& threadManager
= stdcxx::shared_ptr<ThreadManager>())
: TServer(processorFactory), serverTransport_(serverTransport) {
init();
setInputTransportFactory(inputTransportFactory);
setOutputTransportFactory(outputTransportFactory);
@ -364,17 +358,16 @@ public:
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);
TNonblockingServer(const stdcxx::shared_ptr<TProcessor>& processor,
const stdcxx::shared_ptr<TTransportFactory>& inputTransportFactory,
const stdcxx::shared_ptr<TTransportFactory>& outputTransportFactory,
const stdcxx::shared_ptr<TProtocolFactory>& inputProtocolFactory,
const stdcxx::shared_ptr<TProtocolFactory>& outputProtocolFactory,
const stdcxx::shared_ptr<apache::thrift::transport::TNonblockingServerTransport>& serverTransport,
const stdcxx::shared_ptr<ThreadManager>& threadManager
= stdcxx::shared_ptr<ThreadManager>())
: TServer(processor), serverTransport_(serverTransport) {
init();
setInputTransportFactory(inputTransportFactory);
setOutputTransportFactory(outputTransportFactory);
@ -385,11 +378,11 @@ public:
~TNonblockingServer();
void setThreadManager(boost::shared_ptr<ThreadManager> threadManager);
void setThreadManager(stdcxx::shared_ptr<ThreadManager> threadManager);
int getListenPort() { return listenPort_; }
int getListenPort() { return serverTransport_->getListenPort(); }
boost::shared_ptr<ThreadManager> getThreadManager() { return threadManager_; }
stdcxx::shared_ptr<ThreadManager> getThreadManager() { return threadManager_; }
/**
* Sets the number of IO threads used by this server. Can only be used before
@ -428,7 +421,7 @@ public:
bool isThreadPoolProcessing() const { return threadPoolProcessing_; }
void addTask(boost::shared_ptr<Runnable> task) {
void addTask(stdcxx::shared_ptr<Runnable> task) {
threadManager_->add(task, 0LL, taskExpireTime_);
}
@ -688,14 +681,6 @@ public:
/// 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)
*
@ -724,7 +709,7 @@ private:
*
* @param task the runnable associated with the expired task.
*/
void expireClose(boost::shared_ptr<Runnable> task);
void expireClose(stdcxx::shared_ptr<Runnable> task);
/**
* Return an initialized connection object. Creates or recovers from
@ -736,7 +721,7 @@ private:
* @param addrLen the length of addr
* @return pointer to initialized TConnection object.
*/
TConnection* createConnection(THRIFT_SOCKET socket, const sockaddr* addr, socklen_t addrLen);
TConnection* createConnection(stdcxx::shared_ptr<TSocket> socket);
/**
* Returns a connection to pool or deletion. If the connection pool
@ -780,10 +765,10 @@ public:
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_; }
stdcxx::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; }
void setThread(const stdcxx::shared_ptr<Thread>& t) { thread_ = t; }
// Used by TConnection objects to indicate processing has finished.
bool notify(TNonblockingServer::TConnection* conn);
@ -868,7 +853,7 @@ private:
evutil_socket_t notificationPipeFDs_[2];
/// Actual IO Thread
boost::shared_ptr<Thread> thread_;
stdcxx::shared_ptr<Thread> thread_;
};
}
}

View file

@ -25,7 +25,7 @@
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/concurrency/Thread.h>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
@ -58,8 +58,8 @@ public:
/**
* 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) {
virtual void* createContext(stdcxx::shared_ptr<TProtocol> input,
stdcxx::shared_ptr<TProtocol> output) {
(void)input;
(void)output;
return NULL;
@ -70,8 +70,8 @@ public:
* context.
*/
virtual void deleteContext(void* serverContext,
boost::shared_ptr<TProtocol> input,
boost::shared_ptr<TProtocol> output) {
stdcxx::shared_ptr<TProtocol> input,
stdcxx::shared_ptr<TProtocol> output) {
(void)serverContext;
(void)input;
(void)output;
@ -80,7 +80,7 @@ public:
/**
* Called when a client is about to call the processor.
*/
virtual void processContext(void* serverContext, boost::shared_ptr<TTransport> transport) {
virtual void processContext(void* serverContext, stdcxx::shared_ptr<TTransport> transport) {
(void)serverContext;
(void)transport;
}
@ -107,62 +107,62 @@ public:
// Allows running the server as a Runnable thread
virtual void run() { serve(); }
boost::shared_ptr<TProcessorFactory> getProcessorFactory() { return processorFactory_; }
stdcxx::shared_ptr<TProcessorFactory> getProcessorFactory() { return processorFactory_; }
boost::shared_ptr<TServerTransport> getServerTransport() { return serverTransport_; }
stdcxx::shared_ptr<TServerTransport> getServerTransport() { return serverTransport_; }
boost::shared_ptr<TTransportFactory> getInputTransportFactory() { return inputTransportFactory_; }
stdcxx::shared_ptr<TTransportFactory> getInputTransportFactory() { return inputTransportFactory_; }
boost::shared_ptr<TTransportFactory> getOutputTransportFactory() {
stdcxx::shared_ptr<TTransportFactory> getOutputTransportFactory() {
return outputTransportFactory_;
}
boost::shared_ptr<TProtocolFactory> getInputProtocolFactory() { return inputProtocolFactory_; }
stdcxx::shared_ptr<TProtocolFactory> getInputProtocolFactory() { return inputProtocolFactory_; }
boost::shared_ptr<TProtocolFactory> getOutputProtocolFactory() { return outputProtocolFactory_; }
stdcxx::shared_ptr<TProtocolFactory> getOutputProtocolFactory() { return outputProtocolFactory_; }
boost::shared_ptr<TServerEventHandler> getEventHandler() { return eventHandler_; }
stdcxx::shared_ptr<TServerEventHandler> getEventHandler() { return eventHandler_; }
protected:
TServer(const boost::shared_ptr<TProcessorFactory>& processorFactory)
TServer(const stdcxx::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()));
setInputTransportFactory(stdcxx::shared_ptr<TTransportFactory>(new TTransportFactory()));
setOutputTransportFactory(stdcxx::shared_ptr<TTransportFactory>(new TTransportFactory()));
setInputProtocolFactory(stdcxx::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
setOutputProtocolFactory(stdcxx::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
}
TServer(const boost::shared_ptr<TProcessor>& processor)
TServer(const stdcxx::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()));
setInputTransportFactory(stdcxx::shared_ptr<TTransportFactory>(new TTransportFactory()));
setOutputTransportFactory(stdcxx::shared_ptr<TTransportFactory>(new TTransportFactory()));
setInputProtocolFactory(stdcxx::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
setOutputProtocolFactory(stdcxx::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
}
TServer(const boost::shared_ptr<TProcessorFactory>& processorFactory,
const boost::shared_ptr<TServerTransport>& serverTransport)
TServer(const stdcxx::shared_ptr<TProcessorFactory>& processorFactory,
const stdcxx::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()));
setInputTransportFactory(stdcxx::shared_ptr<TTransportFactory>(new TTransportFactory()));
setOutputTransportFactory(stdcxx::shared_ptr<TTransportFactory>(new TTransportFactory()));
setInputProtocolFactory(stdcxx::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
setOutputProtocolFactory(stdcxx::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
}
TServer(const boost::shared_ptr<TProcessor>& processor,
const boost::shared_ptr<TServerTransport>& serverTransport)
TServer(const stdcxx::shared_ptr<TProcessor>& processor,
const stdcxx::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()));
setInputTransportFactory(stdcxx::shared_ptr<TTransportFactory>(new TTransportFactory()));
setOutputTransportFactory(stdcxx::shared_ptr<TTransportFactory>(new TTransportFactory()));
setInputProtocolFactory(stdcxx::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
setOutputProtocolFactory(stdcxx::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)
TServer(const stdcxx::shared_ptr<TProcessorFactory>& processorFactory,
const stdcxx::shared_ptr<TServerTransport>& serverTransport,
const stdcxx::shared_ptr<TTransportFactory>& transportFactory,
const stdcxx::shared_ptr<TProtocolFactory>& protocolFactory)
: processorFactory_(processorFactory),
serverTransport_(serverTransport),
inputTransportFactory_(transportFactory),
@ -170,10 +170,10 @@ protected:
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)
TServer(const stdcxx::shared_ptr<TProcessor>& processor,
const stdcxx::shared_ptr<TServerTransport>& serverTransport,
const stdcxx::shared_ptr<TTransportFactory>& transportFactory,
const stdcxx::shared_ptr<TProtocolFactory>& protocolFactory)
: processorFactory_(new TSingletonProcessorFactory(processor)),
serverTransport_(serverTransport),
inputTransportFactory_(transportFactory),
@ -181,12 +181,12 @@ protected:
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)
TServer(const stdcxx::shared_ptr<TProcessorFactory>& processorFactory,
const stdcxx::shared_ptr<TServerTransport>& serverTransport,
const stdcxx::shared_ptr<TTransportFactory>& inputTransportFactory,
const stdcxx::shared_ptr<TTransportFactory>& outputTransportFactory,
const stdcxx::shared_ptr<TProtocolFactory>& inputProtocolFactory,
const stdcxx::shared_ptr<TProtocolFactory>& outputProtocolFactory)
: processorFactory_(processorFactory),
serverTransport_(serverTransport),
inputTransportFactory_(inputTransportFactory),
@ -194,12 +194,12 @@ protected:
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)
TServer(const stdcxx::shared_ptr<TProcessor>& processor,
const stdcxx::shared_ptr<TServerTransport>& serverTransport,
const stdcxx::shared_ptr<TTransportFactory>& inputTransportFactory,
const stdcxx::shared_ptr<TTransportFactory>& outputTransportFactory,
const stdcxx::shared_ptr<TProtocolFactory>& inputProtocolFactory,
const stdcxx::shared_ptr<TProtocolFactory>& outputProtocolFactory)
: processorFactory_(new TSingletonProcessorFactory(processor)),
serverTransport_(serverTransport),
inputTransportFactory_(inputTransportFactory),
@ -214,9 +214,9 @@ protected:
* 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) {
stdcxx::shared_ptr<TProcessor> getProcessor(stdcxx::shared_ptr<TProtocol> inputProtocol,
stdcxx::shared_ptr<TProtocol> outputProtocol,
stdcxx::shared_ptr<TTransport> transport) {
TConnectionInfo connInfo;
connInfo.input = inputProtocol;
connInfo.output = outputProtocol;
@ -225,35 +225,35 @@ protected:
}
// Class variables
boost::shared_ptr<TProcessorFactory> processorFactory_;
boost::shared_ptr<TServerTransport> serverTransport_;
stdcxx::shared_ptr<TProcessorFactory> processorFactory_;
stdcxx::shared_ptr<TServerTransport> serverTransport_;
boost::shared_ptr<TTransportFactory> inputTransportFactory_;
boost::shared_ptr<TTransportFactory> outputTransportFactory_;
stdcxx::shared_ptr<TTransportFactory> inputTransportFactory_;
stdcxx::shared_ptr<TTransportFactory> outputTransportFactory_;
boost::shared_ptr<TProtocolFactory> inputProtocolFactory_;
boost::shared_ptr<TProtocolFactory> outputProtocolFactory_;
stdcxx::shared_ptr<TProtocolFactory> inputProtocolFactory_;
stdcxx::shared_ptr<TProtocolFactory> outputProtocolFactory_;
boost::shared_ptr<TServerEventHandler> eventHandler_;
stdcxx::shared_ptr<TServerEventHandler> eventHandler_;
public:
void setInputTransportFactory(boost::shared_ptr<TTransportFactory> inputTransportFactory) {
void setInputTransportFactory(stdcxx::shared_ptr<TTransportFactory> inputTransportFactory) {
inputTransportFactory_ = inputTransportFactory;
}
void setOutputTransportFactory(boost::shared_ptr<TTransportFactory> outputTransportFactory) {
void setOutputTransportFactory(stdcxx::shared_ptr<TTransportFactory> outputTransportFactory) {
outputTransportFactory_ = outputTransportFactory;
}
void setInputProtocolFactory(boost::shared_ptr<TProtocolFactory> inputProtocolFactory) {
void setInputProtocolFactory(stdcxx::shared_ptr<TProtocolFactory> inputProtocolFactory) {
inputProtocolFactory_ = inputProtocolFactory;
}
void setOutputProtocolFactory(boost::shared_ptr<TProtocolFactory> outputProtocolFactory) {
void setOutputProtocolFactory(stdcxx::shared_ptr<TProtocolFactory> outputProtocolFactory) {
outputProtocolFactory_ = outputProtocolFactory;
}
void setServerEventHandler(boost::shared_ptr<TServerEventHandler> eventHandler) {
void setServerEventHandler(stdcxx::shared_ptr<TServerEventHandler> eventHandler) {
eventHandler_ = eventHandler;
}
};

View file

@ -18,7 +18,6 @@
*/
#include <algorithm>
#include <boost/bind.hpp>
#include <stdexcept>
#include <stdint.h>
#include <thrift/server/TServerFramework.h>
@ -28,14 +27,14 @@ namespace thrift {
namespace server {
using apache::thrift::concurrency::Synchronized;
using apache::thrift::protocol::TProtocol;
using apache::thrift::protocol::TProtocolFactory;
using apache::thrift::stdcxx::bind;
using apache::thrift::stdcxx::shared_ptr;
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,
@ -162,7 +161,7 @@ void TServerFramework::serve() {
outputProtocol,
eventHandler_,
client),
bind(&TServerFramework::disposeConnectedClient, this, _1)));
bind(&TServerFramework::disposeConnectedClient, this, stdcxx::placeholders::_1)));
} catch (TTransportException& ttx) {
releaseOneDescriptor("inputTransport", inputTransport);
@ -221,7 +220,7 @@ void TServerFramework::stop() {
serverTransport_->interrupt();
}
void TServerFramework::newlyConnectedClient(const boost::shared_ptr<TConnectedClient>& pClient) {
void TServerFramework::newlyConnectedClient(const shared_ptr<TConnectedClient>& pClient) {
{
Synchronized sync(mon_);
++clients_;

View file

@ -20,7 +20,7 @@
#ifndef _THRIFT_SERVER_TSERVERFRAMEWORK_H_
#define _THRIFT_SERVER_TSERVERFRAMEWORK_H_ 1
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
#include <stdint.h>
#include <thrift/TProcessor.h>
#include <thrift/concurrency/Monitor.h>
@ -48,32 +48,32 @@ namespace server {
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);
const stdcxx::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
const stdcxx::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);
const stdcxx::shared_ptr<apache::thrift::TProcessor>& processor,
const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
const stdcxx::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);
const stdcxx::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
const stdcxx::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);
const stdcxx::shared_ptr<apache::thrift::TProcessor>& processor,
const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory);
virtual ~TServerFramework();
@ -130,7 +130,7 @@ protected:
*
* \param[in] pClient the newly connected client
*/
virtual void onClientConnected(const boost::shared_ptr<TConnectedClient>& pClient) = 0;
virtual void onClientConnected(const stdcxx::shared_ptr<TConnectedClient>& pClient) = 0;
/**
* A client has disconnected.
@ -149,7 +149,7 @@ private:
* 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);
void newlyConnectedClient(const stdcxx::shared_ptr<TConnectedClient>& pClient);
/**
* Smart pointer client deletion.

View file

@ -29,7 +29,7 @@ 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 stdcxx::shared_ptr;
using std::string;
TSimpleServer::TSimpleServer(const shared_ptr<TProcessorFactory>& processorFactory,

View file

@ -34,37 +34,37 @@ namespace server {
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);
const stdcxx::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
const stdcxx::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);
const stdcxx::shared_ptr<apache::thrift::TProcessor>& processor,
const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
const stdcxx::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);
const stdcxx::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
const stdcxx::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);
const stdcxx::shared_ptr<apache::thrift::TProcessor>& processor,
const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory);
virtual ~TSimpleServer();
protected:
virtual void onClientConnected(const boost::shared_ptr<TConnectedClient>& pClient) /* override */;
virtual void onClientConnected(const stdcxx::shared_ptr<TConnectedClient>& pClient) /* override */;
virtual void onClientDisconnected(TConnectedClient* pClient) /* override */;
private:

View file

@ -30,7 +30,7 @@ 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 stdcxx::shared_ptr;
using std::string;
TThreadPoolServer::TThreadPoolServer(const shared_ptr<TProcessorFactory>& processorFactory,
@ -115,7 +115,7 @@ void TThreadPoolServer::setTaskExpiration(int64_t value) {
taskExpiration_ = value;
}
boost::shared_ptr<apache::thrift::concurrency::ThreadManager>
stdcxx::shared_ptr<apache::thrift::concurrency::ThreadManager>
TThreadPoolServer::getThreadManager() const {
return threadManager_;
}

View file

@ -34,39 +34,39 @@ namespace server {
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
const stdcxx::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory,
const stdcxx::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
const stdcxx::shared_ptr<apache::thrift::TProcessor>& processor,
const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory,
const stdcxx::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
const stdcxx::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory,
const stdcxx::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
const stdcxx::shared_ptr<apache::thrift::TProcessor>& processor,
const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory,
const stdcxx::shared_ptr<apache::thrift::concurrency::ThreadManager>& threadManager
= apache::thrift::concurrency::ThreadManager::newSimpleThreadManager());
virtual ~TThreadPoolServer();
@ -83,13 +83,13 @@ public:
virtual int64_t getTaskExpiration() const;
virtual void setTaskExpiration(int64_t value);
virtual boost::shared_ptr<apache::thrift::concurrency::ThreadManager> getThreadManager() const;
virtual stdcxx::shared_ptr<apache::thrift::concurrency::ThreadManager> getThreadManager() const;
protected:
virtual void onClientConnected(const boost::shared_ptr<TConnectedClient>& pClient) /* override */;
virtual void onClientConnected(const stdcxx::shared_ptr<TConnectedClient>& pClient) /* override */;
virtual void onClientDisconnected(TConnectedClient* pClient) /* override */;
boost::shared_ptr<apache::thrift::concurrency::ThreadManager> threadManager_;
stdcxx::shared_ptr<apache::thrift::concurrency::ThreadManager> threadManager_;
boost::atomic<int64_t> timeout_;
boost::atomic<int64_t> taskExpiration_;
};

View file

@ -17,11 +17,8 @@
* under the License.
*/
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <string>
#include <thrift/stdcxx.h>
#include <thrift/concurrency/PlatformThreadFactory.h>
#include <thrift/server/TThreadedServer.h>
@ -35,11 +32,12 @@ using apache::thrift::concurrency::Thread;
using apache::thrift::concurrency::ThreadFactory;
using apache::thrift::protocol::TProtocol;
using apache::thrift::protocol::TProtocolFactory;
using apache::thrift::stdcxx::make_shared;
using apache::thrift::stdcxx::shared_ptr;
using apache::thrift::transport::TServerTransport;
using apache::thrift::transport::TTransport;
using apache::thrift::transport::TTransportException;
using apache::thrift::transport::TTransportFactory;
using boost::shared_ptr;
TThreadedServer::TThreadedServer(const shared_ptr<TProcessorFactory>& processorFactory,
const shared_ptr<TServerTransport>& serverTransport,
@ -117,8 +115,8 @@ void TThreadedServer::drainDeadClients() {
void TThreadedServer::onClientConnected(const shared_ptr<TConnectedClient>& pClient) {
Synchronized sync(clientMonitor_);
boost::shared_ptr<TConnectedClientRunner> pRunnable = boost::make_shared<TConnectedClientRunner>(pClient);
boost::shared_ptr<Thread> pThread = threadFactory_->newThread(pRunnable);
shared_ptr<TConnectedClientRunner> pRunnable = make_shared<TConnectedClientRunner>(pClient);
shared_ptr<Thread> pThread = threadFactory_->newThread(pRunnable);
pRunnable->thread(pThread);
activeClientMap_.insert(ClientMap::value_type(pClient.get(), pThread));
pThread->start();
@ -128,15 +126,17 @@ void TThreadedServer::onClientDisconnected(TConnectedClient* pClient) {
Synchronized sync(clientMonitor_);
drainDeadClients(); // use the outgoing thread to do some maintenance on our dead client backlog
ClientMap::iterator it = activeClientMap_.find(pClient);
ClientMap::iterator end = it;
deadClientMap_.insert(it, ++end);
activeClientMap_.erase(it);
if (it != activeClientMap_.end()) {
ClientMap::iterator end = it;
deadClientMap_.insert(it, ++end);
activeClientMap_.erase(it);
}
if (activeClientMap_.empty()) {
clientMonitor_.notify();
}
}
TThreadedServer::TConnectedClientRunner::TConnectedClientRunner(const boost::shared_ptr<TConnectedClient>& pClient)
TThreadedServer::TConnectedClientRunner::TConnectedClientRunner(const shared_ptr<TConnectedClient>& pClient)
: pClient_(pClient) {
}

View file

@ -38,43 +38,43 @@ namespace server {
class TThreadedServer : public TServerFramework {
public:
TThreadedServer(
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::ThreadFactory>& threadFactory
= boost::shared_ptr<apache::thrift::concurrency::ThreadFactory>(
const stdcxx::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory,
const stdcxx::shared_ptr<apache::thrift::concurrency::ThreadFactory>& threadFactory
= stdcxx::shared_ptr<apache::thrift::concurrency::ThreadFactory>(
new apache::thrift::concurrency::PlatformThreadFactory(false)));
TThreadedServer(
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::ThreadFactory>& threadFactory
= boost::shared_ptr<apache::thrift::concurrency::ThreadFactory>(
const stdcxx::shared_ptr<apache::thrift::TProcessor>& processor,
const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory,
const stdcxx::shared_ptr<apache::thrift::concurrency::ThreadFactory>& threadFactory
= stdcxx::shared_ptr<apache::thrift::concurrency::ThreadFactory>(
new apache::thrift::concurrency::PlatformThreadFactory(false)));
TThreadedServer(
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::ThreadFactory>& threadFactory
= boost::shared_ptr<apache::thrift::concurrency::ThreadFactory>(
const stdcxx::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory,
const stdcxx::shared_ptr<apache::thrift::concurrency::ThreadFactory>& threadFactory
= stdcxx::shared_ptr<apache::thrift::concurrency::ThreadFactory>(
new apache::thrift::concurrency::PlatformThreadFactory(false)));
TThreadedServer(
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::ThreadFactory>& threadFactory
= boost::shared_ptr<apache::thrift::concurrency::ThreadFactory>(
const stdcxx::shared_ptr<apache::thrift::TProcessor>& processor,
const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory,
const stdcxx::shared_ptr<apache::thrift::concurrency::ThreadFactory>& threadFactory
= stdcxx::shared_ptr<apache::thrift::concurrency::ThreadFactory>(
new apache::thrift::concurrency::PlatformThreadFactory(false)));
virtual ~TThreadedServer();
@ -95,14 +95,14 @@ protected:
/**
* Implementation of TServerFramework::onClientConnected
*/
virtual void onClientConnected(const boost::shared_ptr<TConnectedClient>& pClient) /* override */;
virtual void onClientConnected(const stdcxx::shared_ptr<TConnectedClient>& pClient) /* override */;
/**
* Implementation of TServerFramework::onClientDisconnected
*/
virtual void onClientDisconnected(TConnectedClient *pClient) /* override */;
boost::shared_ptr<apache::thrift::concurrency::ThreadFactory> threadFactory_;
stdcxx::shared_ptr<apache::thrift::concurrency::ThreadFactory> threadFactory_;
/**
* A helper wrapper used to wrap the client in something we can use to maintain
@ -114,16 +114,16 @@ protected:
class TConnectedClientRunner : public apache::thrift::concurrency::Runnable
{
public:
TConnectedClientRunner(const boost::shared_ptr<TConnectedClient>& pClient);
TConnectedClientRunner(const stdcxx::shared_ptr<TConnectedClient>& pClient);
virtual ~TConnectedClientRunner();
void run() /* override */;
private:
boost::shared_ptr<TConnectedClient> pClient_;
stdcxx::shared_ptr<TConnectedClient> pClient_;
};
apache::thrift::concurrency::Monitor clientMonitor_;
typedef std::map<TConnectedClient *, boost::shared_ptr<apache::thrift::concurrency::Thread> > ClientMap;
typedef std::map<TConnectedClient *, stdcxx::shared_ptr<apache::thrift::concurrency::Thread> > ClientMap;
/**
* A map of active clients

View 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_STDCXX_H_
#define _THRIFT_STDCXX_H_ 1
#include <boost/config.hpp>
#include <boost/version.hpp>
///////////////////////////////////////////////////////////////////
//
// functional (function, bind)
//
///////////////////////////////////////////////////////////////////
#if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) || (defined(_MSC_VER) && _MSC_VER < 1800) || defined(FORCE_BOOST_FUNCTIONAL)
#if (BOOST_VERSION <= 106500)
#include <boost/tr1/functional.hpp>
#else
#include <tr1/functional>
#endif
#define _THRIFT_FUNCTIONAL_TR1_ 1
#endif
#if _THRIFT_FUNCTIONAL_TR1_
namespace apache { namespace thrift { namespace stdcxx {
using ::std::tr1::bind;
using ::std::tr1::function;
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;
using ::std::tr1::placeholders::_7;
using ::std::tr1::placeholders::_8;
using ::std::tr1::placeholders::_9;
} // apache::thrift::stdcxx::placeholders
}}} // apache::thrift::stdcxx
#else
#include <functional>
namespace apache { namespace thrift { namespace stdcxx {
using ::std::bind;
using ::std::function;
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;
using ::std::placeholders::_7;
using ::std::placeholders::_8;
using ::std::placeholders::_9;
} // apache::thrift::stdcxx::placeholders
}}} // apache::thrift::stdcxx
#endif
///////////////////////////////////////////////////////////////////
//
// Smart Pointers
//
///////////////////////////////////////////////////////////////////
// We can use std for memory functions only if the compiler supports template aliasing
// The macro BOOST_NO_CXX11_SMART_PTR is defined as 1 under Visual Studio 2010 and 2012
// which do not support the feature, so we must continue to use C++98 and boost on them.
// We cannot use __cplusplus to detect this either, since Microsoft advertises an older one.
#if defined(BOOST_NO_CXX11_SMART_PTR) || (defined(_MSC_VER) && _MSC_VER < 1800) || defined(FORCE_BOOST_SMART_PTR)
#include <boost/smart_ptr.hpp>
#else
#include <memory>
#endif
namespace apache { namespace thrift { namespace stdcxx {
#if defined(BOOST_NO_CXX11_SMART_PTR) || (defined(_MSC_VER) && _MSC_VER < 1800) || defined(FORCE_BOOST_SMART_PTR)
using ::boost::const_pointer_cast;
using ::boost::dynamic_pointer_cast;
using ::boost::enable_shared_from_this;
using ::boost::make_shared;
using ::boost::scoped_ptr;
using ::boost::shared_ptr;
using ::boost::static_pointer_cast;
using ::boost::weak_ptr;
#else
using ::std::const_pointer_cast;
using ::std::dynamic_pointer_cast;
using ::std::enable_shared_from_this;
using ::std::make_shared;
template <typename T> using scoped_ptr = std::unique_ptr<T>; // compiler must support template aliasing
using ::std::shared_ptr;
using ::std::static_pointer_cast;
using ::std::weak_ptr;
#endif
}}} // apache::thrift::stdcxx
#endif // #ifndef _THRIFT_STDCXX_H_

View file

@ -23,6 +23,7 @@
# define _THRIFT_TRANSPORT_PLATFORM_SOCKET_H_
#ifdef _WIN32
# include <winsock2.h>
# define THRIFT_GET_SOCKET_ERROR ::WSAGetLastError()
# define THRIFT_ERRNO (*_errno())
# define THRIFT_EINPROGRESS WSAEINPROGRESS
@ -50,6 +51,8 @@
# define THRIFT_LSEEK _lseek
# define THRIFT_WRITE _write
# define THRIFT_READ _read
# define THRIFT_IOCTL_SOCKET ioctlsocket
# define THRIFT_IOCTL_SOCKET_NUM_BYTES_TYPE u_long
# define THRIFT_FSTAT _fstat
# define THRIFT_STAT _stat
# ifdef _WIN32_WCE
@ -78,6 +81,9 @@
# define THRIFT_POLLOUT POLLOUT
# endif //WINVER
# define THRIFT_SHUT_RDWR SD_BOTH
# if !defined(AI_ADDRCONFIG)
# define AI_ADDRCONFIG 0x00000400
# endif
#else //not _WIN32
# include <errno.h>
# define THRIFT_GET_SOCKET_ERROR errno
@ -107,6 +113,8 @@
# define THRIFT_LSEEK lseek
# define THRIFT_WRITE write
# define THRIFT_READ read
# define THRIFT_IOCTL_SOCKET ioctl
# define THRIFT_IOCTL_SOCKET_NUM_BYTES_TYPE int
# define THRIFT_STAT stat
# define THRIFT_FSTAT fstat
# define THRIFT_GAI_STRERROR gai_strerror

View file

@ -361,10 +361,14 @@ void TMemoryBuffer::ensureCanWrite(uint32_t len) {
}
// Grow the buffer as necessary.
uint32_t new_size = bufferSize_;
uint64_t new_size = bufferSize_;
while (len > avail) {
new_size = new_size > 0 ? new_size * 2 : 1;
avail = available_write() + (new_size - bufferSize_);
if (new_size > maxBufferSize_) {
throw TTransportException(TTransportException::BAD_ARGS,
"Internal buffer size overflow");
}
avail = available_write() + (static_cast<uint32_t>(new_size) - bufferSize_);
}
// Allocate into a new pointer so we don't bork ours if it fails.
@ -378,7 +382,7 @@ void TMemoryBuffer::ensureCanWrite(uint32_t len) {
wBase_ = new_buffer + (wBase_ - buffer_);
wBound_ = new_buffer + new_size;
buffer_ = new_buffer;
bufferSize_ = new_size;
bufferSize_ = static_cast<uint32_t>(new_size);
}
void TMemoryBuffer::writeSlow(const uint8_t* buf, uint32_t len) {

View file

@ -186,7 +186,7 @@ public:
static const int DEFAULT_BUFFER_SIZE = 512;
/// Use default buffer sizes.
TBufferedTransport(boost::shared_ptr<TTransport> transport)
TBufferedTransport(stdcxx::shared_ptr<TTransport> transport)
: transport_(transport),
rBufSize_(DEFAULT_BUFFER_SIZE),
wBufSize_(DEFAULT_BUFFER_SIZE),
@ -196,7 +196,7 @@ public:
}
/// Use specified buffer sizes.
TBufferedTransport(boost::shared_ptr<TTransport> transport, uint32_t sz)
TBufferedTransport(stdcxx::shared_ptr<TTransport> transport, uint32_t sz)
: transport_(transport),
rBufSize_(sz),
wBufSize_(sz),
@ -206,7 +206,7 @@ public:
}
/// Use specified read and write buffer sizes.
TBufferedTransport(boost::shared_ptr<TTransport> transport, uint32_t rsz, uint32_t wsz)
TBufferedTransport(stdcxx::shared_ptr<TTransport> transport, uint32_t rsz, uint32_t wsz)
: transport_(transport),
rBufSize_(rsz),
wBufSize_(wsz),
@ -255,7 +255,7 @@ public:
*/
virtual const uint8_t* borrowSlow(uint8_t* buf, uint32_t* len);
boost::shared_ptr<TTransport> getUnderlyingTransport() { return transport_; }
stdcxx::shared_ptr<TTransport> getUnderlyingTransport() { return transport_; }
/*
* TVirtualTransport provides a default implementation of readAll().
@ -270,7 +270,7 @@ protected:
// Write size never changes.
}
boost::shared_ptr<TTransport> transport_;
stdcxx::shared_ptr<TTransport> transport_;
uint32_t rBufSize_;
uint32_t wBufSize_;
@ -291,8 +291,8 @@ public:
/**
* Wraps the transport into a buffered one.
*/
virtual boost::shared_ptr<TTransport> getTransport(boost::shared_ptr<TTransport> trans) {
return boost::shared_ptr<TTransport>(new TBufferedTransport(trans));
virtual stdcxx::shared_ptr<TTransport> getTransport(stdcxx::shared_ptr<TTransport> trans) {
return stdcxx::shared_ptr<TTransport>(new TBufferedTransport(trans));
}
};
@ -319,7 +319,7 @@ public:
initPointers();
}
TFramedTransport(boost::shared_ptr<TTransport> transport)
TFramedTransport(stdcxx::shared_ptr<TTransport> transport)
: transport_(transport),
rBufSize_(0),
wBufSize_(DEFAULT_BUFFER_SIZE),
@ -330,7 +330,7 @@ public:
initPointers();
}
TFramedTransport(boost::shared_ptr<TTransport> transport,
TFramedTransport(stdcxx::shared_ptr<TTransport> transport,
uint32_t sz,
uint32_t bufReclaimThresh = (std::numeric_limits<uint32_t>::max)())
: transport_(transport),
@ -366,7 +366,7 @@ public:
const uint8_t* borrowSlow(uint8_t* buf, uint32_t* len);
boost::shared_ptr<TTransport> getUnderlyingTransport() { return transport_; }
stdcxx::shared_ptr<TTransport> getUnderlyingTransport() { return transport_; }
/*
* TVirtualTransport provides a default implementation of readAll().
@ -407,7 +407,7 @@ protected:
this->write((uint8_t*)&pad, sizeof(pad));
}
boost::shared_ptr<TTransport> transport_;
stdcxx::shared_ptr<TTransport> transport_;
uint32_t rBufSize_;
uint32_t wBufSize_;
@ -430,8 +430,8 @@ public:
/**
* Wraps the transport into a framed one.
*/
virtual boost::shared_ptr<TTransport> getTransport(boost::shared_ptr<TTransport> trans) {
return boost::shared_ptr<TTransport>(new TFramedTransport(trans));
virtual stdcxx::shared_ptr<TTransport> getTransport(stdcxx::shared_ptr<TTransport> trans) {
return stdcxx::shared_ptr<TTransport>(new TFramedTransport(trans));
}
};
@ -448,11 +448,14 @@ class TMemoryBuffer : public TVirtualTransport<TMemoryBuffer, TBufferBase> {
private:
// Common initialization done by all constructors.
void initCommon(uint8_t* buf, uint32_t size, bool owner, uint32_t wPos) {
maxBufferSize_ = std::numeric_limits<uint32_t>::max();
if (buf == NULL && size != 0) {
assert(owner);
buf = (uint8_t*)std::malloc(size);
if (buf == NULL) {
throw std::bad_alloc();
throw std::bad_alloc();
}
}
@ -673,6 +676,29 @@ public:
*/
uint32_t readAll(uint8_t* buf, uint32_t len) { return TBufferBase::readAll(buf, len); }
//! \brief Get the current buffer size
//! \returns the current buffer size
uint32_t getBufferSize() const {
return bufferSize_;
}
//! \brief Get the current maximum buffer size
//! \returns the current maximum buffer size
uint32_t getMaxBufferSize() const {
return maxBufferSize_;
}
//! \brief Change the maximum buffer size
//! \param[in] maxSize the new maximum buffer size allowed to grow to
//! \throws TTransportException(BAD_ARGS) if maxSize is less than the current buffer size
void setMaxBufferSize(uint32_t maxSize) {
if (maxSize < bufferSize_) {
throw TTransportException(TTransportException::BAD_ARGS,
"Maximum buffer size would be less than current buffer size");
}
maxBufferSize_ = maxSize;
}
protected:
void swap(TMemoryBuffer& that) {
using std::swap;
@ -705,6 +731,9 @@ protected:
// Allocated buffer size
uint32_t bufferSize_;
// Maximum allowed size
uint32_t maxBufferSize_;
// Is this object the owner of the buffer?
bool owner_;

View file

@ -31,7 +31,7 @@
#include <io.h>
#endif
using namespace std;
using std::string;
namespace apache {
namespace thrift {

View file

@ -24,6 +24,15 @@
#include <thrift/transport/PlatformSocket.h>
#include <thrift/concurrency/FunctionRunner.h>
#include <boost/version.hpp>
#if (BOOST_VERSION >= 105700)
#include <boost/move/unique_ptr.hpp>
using boost::movelib::unique_ptr;
#else
#include <boost/interprocess/smart_ptr/unique_ptr.hpp>
using boost::interprocess::unique_ptr;
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#else
@ -52,9 +61,12 @@ namespace apache {
namespace thrift {
namespace transport {
using boost::scoped_ptr;
using boost::shared_ptr;
using namespace std;
using stdcxx::shared_ptr;
using std::cerr;
using std::cout;
using std::endl;
using std::min;
using std::string;
using namespace apache::thrift::protocol;
using namespace apache::thrift::concurrency;
@ -192,6 +204,14 @@ void TFileTransport::write(const uint8_t* buf, uint32_t len) {
enqueueEvent(buf, len);
}
// this is needed until boost 1.57 as the older unique_ptr implementation
// has no default deleter in interprocess
template <class _T>
struct uniqueDeleter
{
void operator()(_T *ptr) const { delete ptr; }
};
void TFileTransport::enqueueEvent(const uint8_t* buf, uint32_t eventLen) {
// can't enqueue more events if file is going to close
if (closing_) {
@ -209,7 +229,7 @@ void TFileTransport::enqueueEvent(const uint8_t* buf, uint32_t eventLen) {
return;
}
std::auto_ptr<eventInfo> toEnqueue(new eventInfo());
unique_ptr<eventInfo, uniqueDeleter<eventInfo> > toEnqueue(new eventInfo());
toEnqueue->eventBuff_ = new uint8_t[(sizeof(uint8_t) * eventLen) + 4];
// first 4 bytes is the event length
@ -363,7 +383,7 @@ void TFileTransport::writerThread() {
while (hasIOError) {
T_ERROR(
"TFileTransport: writer thread going to sleep for %d microseconds due to IO errors",
"TFileTransport: writer thread going to sleep for %u microseconds due to IO errors",
writerThreadIOErrorSleepTime_);
THRIFT_SLEEP_USEC(writerThreadIOErrorSleepTime_);
if (closing_) {
@ -832,7 +852,7 @@ void TFileTransport::seekToChunk(int32_t chunk) {
uint32_t oldReadTimeout = getReadTimeout();
setReadTimeout(NO_TAIL_READ_TIMEOUT);
// keep on reading unti the last event at point of seekChunk call
boost::scoped_ptr<eventInfo> event;
shared_ptr<eventInfo> event;
while ((offset_ + readState_.bufferPtr_) < minEndOffset) {
event.reset(readEvent());
if (event.get() == NULL) {

View file

@ -28,8 +28,7 @@
#include <stdio.h>
#include <boost/atomic.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
#include <thrift/concurrency/Mutex.h>
#include <thrift/concurrency/Monitor.h>
@ -340,7 +339,7 @@ private:
// writer thread
apache::thrift::concurrency::PlatformThreadFactory threadFactory_;
boost::shared_ptr<apache::thrift::concurrency::Thread> writerThread_;
stdcxx::shared_ptr<apache::thrift::concurrency::Thread> writerThread_;
// buffers to hold data before it is flushed. Each element of the buffer stores a msg that
// needs to be written to the file. The buffers are swapped by the writer thread.
@ -349,7 +348,7 @@ private:
// conditions used to block when the buffer is full or empty
Monitor notFull_, notEmpty_;
bool closing_;
boost::atomic<bool> closing_;
// To keep track of whether the buffer has been flushed
Monitor flushed_;
@ -391,14 +390,14 @@ public:
* @param protocolFactory protocol factory
* @param inputTransport file transport
*/
TFileProcessor(boost::shared_ptr<TProcessor> processor,
boost::shared_ptr<TProtocolFactory> protocolFactory,
boost::shared_ptr<TFileReaderTransport> inputTransport);
TFileProcessor(stdcxx::shared_ptr<TProcessor> processor,
stdcxx::shared_ptr<TProtocolFactory> protocolFactory,
stdcxx::shared_ptr<TFileReaderTransport> inputTransport);
TFileProcessor(boost::shared_ptr<TProcessor> processor,
boost::shared_ptr<TProtocolFactory> inputProtocolFactory,
boost::shared_ptr<TProtocolFactory> outputProtocolFactory,
boost::shared_ptr<TFileReaderTransport> inputTransport);
TFileProcessor(stdcxx::shared_ptr<TProcessor> processor,
stdcxx::shared_ptr<TProtocolFactory> inputProtocolFactory,
stdcxx::shared_ptr<TProtocolFactory> outputProtocolFactory,
stdcxx::shared_ptr<TFileReaderTransport> inputTransport);
/**
* Constructor
@ -408,10 +407,10 @@ public:
* @param inputTransport input file transport
* @param output output transport
*/
TFileProcessor(boost::shared_ptr<TProcessor> processor,
boost::shared_ptr<TProtocolFactory> protocolFactory,
boost::shared_ptr<TFileReaderTransport> inputTransport,
boost::shared_ptr<TTransport> outputTransport);
TFileProcessor(stdcxx::shared_ptr<TProcessor> processor,
stdcxx::shared_ptr<TProtocolFactory> protocolFactory,
stdcxx::shared_ptr<TFileReaderTransport> inputTransport,
stdcxx::shared_ptr<TTransport> outputTransport);
/**
* processes events from the file
@ -428,11 +427,11 @@ public:
void processChunk();
private:
boost::shared_ptr<TProcessor> processor_;
boost::shared_ptr<TProtocolFactory> inputProtocolFactory_;
boost::shared_ptr<TProtocolFactory> outputProtocolFactory_;
boost::shared_ptr<TFileReaderTransport> inputTransport_;
boost::shared_ptr<TTransport> outputTransport_;
stdcxx::shared_ptr<TProcessor> processor_;
stdcxx::shared_ptr<TProtocolFactory> inputProtocolFactory_;
stdcxx::shared_ptr<TProtocolFactory> outputProtocolFactory_;
stdcxx::shared_ptr<TFileReaderTransport> inputTransport_;
stdcxx::shared_ptr<TTransport> outputTransport_;
};
}
}

View file

@ -22,20 +22,23 @@
#include <thrift/protocol/TProtocolTypes.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/protocol/TCompactProtocol.h>
#include <thrift/stdcxx.h>
#include <limits>
#include <utility>
#include <cassert>
#include <string>
#include <zlib.h>
#include <string.h>
#include <zlib.h>
using std::map;
using boost::shared_ptr;
using std::string;
using std::vector;
namespace apache {
namespace thrift {
using stdcxx::shared_ptr;
namespace transport {
using namespace apache::thrift::protocol;
@ -172,7 +175,7 @@ bool THeaderTransport::readFrame() {
* Reads a string from ptr, taking care not to reach headerBoundary
* Advances ptr on success
*
* @param str output string
* @param str output string
* @throws CORRUPTED_DATA if size of string exceeds boundary
*/
void THeaderTransport::readString(uint8_t*& ptr,
@ -198,7 +201,10 @@ void THeaderTransport::readHeaderFormat(uint16_t headerSize, uint32_t sz) {
uint8_t* ptr = reinterpret_cast<uint8_t*>(rBuf_.get() + 10);
// Catch integer overflow, check for reasonable header size
assert(headerSize < 16384);
if (headerSize >= 16384) {
throw TTransportException(TTransportException::CORRUPTED_DATA,
"Header size is unreasonable");
}
headerSize *= 4;
const uint8_t* const headerBoundary = ptr + headerSize;
if (headerSize > sz) {
@ -252,7 +258,7 @@ void THeaderTransport::readHeaderFormat(uint16_t headerSize, uint32_t sz) {
}
// Untransform the data section. rBuf will contain result.
untransform(data, sz - (data - rBuf_.get())); // ignore header in size calc
untransform(data, safe_numeric_cast<uint32_t>(static_cast<ptrdiff_t>(sz) - (data - rBuf_.get())));
}
void THeaderTransport::untransform(uint8_t* ptr, uint32_t sz) {
@ -375,7 +381,7 @@ void THeaderTransport::resetProtocol() {
}
uint32_t THeaderTransport::getWriteBytes() {
return wBase_ - wBuf_.get();
return safe_numeric_cast<uint32_t>(wBase_ - wBuf_.get());
}
/**
@ -384,7 +390,7 @@ uint32_t THeaderTransport::getWriteBytes() {
* Automatically advances ptr to after the written portion
*/
void THeaderTransport::writeString(uint8_t*& ptr, const string& str) {
uint32_t strLen = str.length();
int32_t strLen = safe_numeric_cast<int32_t>(str.length());
ptr += writeVarint32(strLen, ptr);
memcpy(ptr, str.c_str(), strLen); // no need to write \0
ptr += strLen;
@ -394,7 +400,7 @@ void THeaderTransport::setHeader(const string& key, const string& value) {
writeHeaders_[key] = value;
}
size_t THeaderTransport::getMaxWriteHeadersSize() const {
uint32_t THeaderTransport::getMaxWriteHeadersSize() const {
size_t maxWriteHeadersSize = 0;
THeaderTransport::StringToStringMap::const_iterator it;
for (it = writeHeaders_.begin(); it != writeHeaders_.end(); ++it) {
@ -402,7 +408,7 @@ size_t THeaderTransport::getMaxWriteHeadersSize() const {
// 2 varints32 + the strings themselves
maxWriteHeadersSize += 5 + 5 + (it->first).length() + (it->second).length();
}
return maxWriteHeadersSize;
return safe_numeric_cast<uint32_t>(maxWriteHeadersSize);
}
void THeaderTransport::clearHeaders() {
@ -431,7 +437,7 @@ void THeaderTransport::flush() {
if (clientType == THRIFT_HEADER_CLIENT_TYPE) {
// header size will need to be updated at the end because of varints.
// Make it big enough here for max varint size, plus 4 for padding.
int headerSize = (2 + getNumTransforms()) * THRIFT_MAX_VARINT32_BYTES + 4;
uint32_t headerSize = (2 + getNumTransforms()) * THRIFT_MAX_VARINT32_BYTES + 4;
// add approximate size of info headers
headerSize += getMaxWriteHeadersSize();
@ -479,11 +485,11 @@ void THeaderTransport::flush() {
// write info headers
// for now only write kv-headers
uint16_t headerCount = writeHeaders_.size();
int32_t headerCount = safe_numeric_cast<int32_t>(writeHeaders_.size());
if (headerCount > 0) {
pkt += writeVarint32(infoIdType::KEYVALUE, pkt);
// Write key-value headers count
pkt += writeVarint32(headerCount, pkt);
pkt += writeVarint32(static_cast<int32_t>(headerCount), pkt);
// Write info headers
map<string, string>::const_iterator it;
for (it = writeHeaders_.begin(); it != writeHeaders_.end(); ++it) {
@ -494,7 +500,7 @@ void THeaderTransport::flush() {
}
// Fixups after varint size calculations
headerSize = (pkt - headerStart);
headerSize = safe_numeric_cast<uint32_t>(pkt - headerStart);
uint8_t padding = 4 - (headerSize % 4);
headerSize += padding;
@ -504,8 +510,13 @@ void THeaderTransport::flush() {
}
// Pkt size
ptrdiff_t szHbp = (headerStart - pktStart - 4);
if (static_cast<uint64_t>(szHbp) > static_cast<uint64_t>(std::numeric_limits<uint32_t>().max()) - (headerSize + haveBytes)) {
throw TTransportException(TTransportException::CORRUPTED_DATA,
"Header section size is unreasonable");
}
szHbo = headerSize + haveBytes // thrift header + payload
+ (headerStart - pktStart - 4); // common header section
+ static_cast<uint32_t>(szHbp); // common header section
headerSizeN = htons(headerSize / 4);
memcpy(headerSizePtr, &headerSizeN, sizeof(headerSizeN));

View file

@ -21,13 +21,20 @@
#define THRIFT_TRANSPORT_THEADERTRANSPORT_H_ 1
#include <bitset>
#include <limits>
#include <vector>
#include <stdexcept>
#include <string>
#include <map>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#elif HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#include <boost/scoped_array.hpp>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
#include <thrift/protocol/TProtocolTypes.h>
#include <thrift/transport/TBufferTransports.h>
@ -68,7 +75,7 @@ public:
static const int THRIFT_MAX_VARINT32_BYTES = 5;
/// Use default buffer sizes.
explicit THeaderTransport(const boost::shared_ptr<TTransport>& transport)
explicit THeaderTransport(const stdcxx::shared_ptr<TTransport>& transport)
: TVirtualTransport(transport),
outTransport_(transport),
protoId(T_COMPACT_PROTOCOL),
@ -81,8 +88,8 @@ public:
initBuffers();
}
THeaderTransport(const boost::shared_ptr<TTransport> inTransport,
const boost::shared_ptr<TTransport> outTransport)
THeaderTransport(const stdcxx::shared_ptr<TTransport> inTransport,
const stdcxx::shared_ptr<TTransport> outTransport)
: TVirtualTransport(inTransport),
outTransport_(outTransport),
protoId(T_COMPACT_PROTOCOL),
@ -135,8 +142,7 @@ public:
void transform(uint8_t* ptr, uint32_t sz);
uint16_t getNumTransforms() const {
int trans = writeTrans_.size();
return trans;
return safe_numeric_cast<uint16_t>(writeTrans_.size());
}
void setTransform(uint16_t transId) { writeTrans_.push_back(transId); }
@ -180,7 +186,7 @@ protected:
setWriteBuffer(wBuf_.get(), wBufSize_);
}
boost::shared_ptr<TTransport> outTransport_;
stdcxx::shared_ptr<TTransport> outTransport_;
// 0 and 16th bits must be 0 to differentiate from framed & unframed
static const uint32_t HEADER_MAGIC = 0x0FFF0000;
@ -204,7 +210,7 @@ protected:
/**
* Returns the maximum number of bytes that write k/v headers can take
*/
size_t getMaxWriteHeadersSize() const;
uint32_t getMaxWriteHeadersSize() const;
struct infoIdType {
enum idType {
@ -259,8 +265,8 @@ public:
/**
* Wraps the transport into a header one.
*/
virtual boost::shared_ptr<TTransport> getTransport(boost::shared_ptr<TTransport> trans) {
return boost::shared_ptr<TTransport>(new THeaderTransport(trans));
virtual stdcxx::shared_ptr<TTransport> getTransport(stdcxx::shared_ptr<TTransport> trans) {
return stdcxx::shared_ptr<TTransport>(new THeaderTransport(trans));
}
};
}

View file

@ -22,23 +22,24 @@
#include <sstream>
#include <boost/algorithm/string.hpp>
#include <thrift/config.h>
#include <thrift/transport/THttpClient.h>
#include <thrift/transport/TSocket.h>
using std::string;
namespace apache {
namespace thrift {
namespace transport {
using namespace std;
THttpClient::THttpClient(boost::shared_ptr<TTransport> transport,
THttpClient::THttpClient(stdcxx::shared_ptr<TTransport> transport,
std::string host,
std::string path)
: THttpTransport(transport), host_(host), path_(path) {
}
THttpClient::THttpClient(string host, int port, string path)
: THttpTransport(boost::shared_ptr<TTransport>(new TSocket(host, port))),
: THttpTransport(stdcxx::shared_ptr<TTransport>(new TSocket(host, port))),
host_(host),
path_(path) {
}
@ -102,7 +103,7 @@ void THttpClient::flush() {
std::ostringstream h;
h << "POST " << path_ << " HTTP/1.1" << CRLF << "Host: " << host_ << CRLF
<< "Content-Type: application/x-thrift" << CRLF << "Content-Length: " << len << CRLF
<< "Accept: application/x-thrift" << CRLF << "User-Agent: Thrift/" << VERSION
<< "Accept: application/x-thrift" << CRLF << "User-Agent: Thrift/" << PACKAGE_VERSION
<< " (C++/THttpClient)" << CRLF << CRLF;
string header = h.str();

View file

@ -28,7 +28,7 @@ namespace transport {
class THttpClient : public THttpTransport {
public:
THttpClient(boost::shared_ptr<TTransport> transport, std::string host, std::string path = "");
THttpClient(stdcxx::shared_ptr<TTransport> transport, std::string host, std::string path = "");
THttpClient(std::string host, int port, std::string path = "");

View file

@ -21,28 +21,31 @@
#include <sstream>
#include <iostream>
#include <thrift/config.h>
#include <thrift/transport/THttpServer.h>
#include <thrift/transport/TSocket.h>
#if defined(_MSC_VER) || defined(__MINGW32__)
#include <Shlwapi.h>
#endif
using std::string;
namespace apache {
namespace thrift {
namespace transport {
using namespace std;
THttpServer::THttpServer(boost::shared_ptr<TTransport> transport) : THttpTransport(transport) {
THttpServer::THttpServer(stdcxx::shared_ptr<TTransport> transport) : THttpTransport(transport) {
}
THttpServer::~THttpServer() {
}
#if defined(_MSC_VER) || defined(__MINGW32__)
#define THRIFT_GMTIME(TM, TIME) gmtime_s(&TM, &TIME)
#define THRIFT_strncasecmp(str1, str2, len) _strnicmp(str1, str2, len)
#define THRIFT_strcasestr(haystack, needle) StrStrIA(haystack, needle)
#else
#define THRIFT_GMTIME(TM, TIME) gmtime_r(&TIME, &TM)
#define THRIFT_strncasecmp(str1, str2, len) strncasecmp(str1, str2, len)
#define THRIFT_strcasestr(haystack, needle) strcasestr(haystack, needle)
#endif
@ -124,7 +127,7 @@ void THttpServer::flush() {
// Construct the HTTP header
std::ostringstream h;
h << "HTTP/1.1 200 OK" << CRLF << "Date: " << getTimeRFC1123() << CRLF << "Server: Thrift/"
<< VERSION << CRLF << "Access-Control-Allow-Origin: *" << CRLF
<< PACKAGE_VERSION << CRLF << "Access-Control-Allow-Origin: *" << CRLF
<< "Content-Type: application/x-thrift" << CRLF << "Content-Length: " << len << CRLF
<< "Connection: Keep-Alive" << CRLF << CRLF;
string header = h.str();
@ -145,18 +148,20 @@ std::string THttpServer::getTimeRFC1123() {
static const char* Months[]
= {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
char buff[128];
time_t t = time(NULL);
tm* broken_t = gmtime(&t);
struct tm tmb;
THRIFT_GMTIME(tmb, t);
sprintf(buff,
"%s, %d %s %d %d:%d:%d GMT",
Days[broken_t->tm_wday],
broken_t->tm_mday,
Months[broken_t->tm_mon],
broken_t->tm_year + 1900,
broken_t->tm_hour,
broken_t->tm_min,
broken_t->tm_sec);
Days[tmb.tm_wday],
tmb.tm_mday,
Months[tmb.tm_mon],
tmb.tm_year + 1900,
tmb.tm_hour,
tmb.tm_min,
tmb.tm_sec);
return std::string(buff);
}
}

View file

@ -28,7 +28,7 @@ namespace transport {
class THttpServer : public THttpTransport {
public:
THttpServer(boost::shared_ptr<TTransport> transport);
THttpServer(stdcxx::shared_ptr<TTransport> transport);
virtual ~THttpServer();
@ -53,8 +53,8 @@ public:
/**
* Wraps the transport into a buffered one.
*/
virtual boost::shared_ptr<TTransport> getTransport(boost::shared_ptr<TTransport> trans) {
return boost::shared_ptr<TTransport>(new THttpServer(trans));
virtual stdcxx::shared_ptr<TTransport> getTransport(stdcxx::shared_ptr<TTransport> trans) {
return stdcxx::shared_ptr<TTransport>(new THttpServer(trans));
}
};
}

View file

@ -21,17 +21,17 @@
#include <thrift/transport/THttpTransport.h>
using std::string;
namespace apache {
namespace thrift {
namespace transport {
using namespace std;
// Yeah, yeah, hacky to put these here, I know.
const char* THttpTransport::CRLF = "\r\n";
const int THttpTransport::CRLF_LEN = 2;
THttpTransport::THttpTransport(boost::shared_ptr<TTransport> transport)
THttpTransport::THttpTransport(stdcxx::shared_ptr<TTransport> transport)
: transport_(transport),
origin_(""),
readHeaders_(true),
@ -84,8 +84,10 @@ uint32_t THttpTransport::readEnd() {
uint32_t THttpTransport::readMoreData() {
uint32_t size;
// Get more data!
refill();
if (httpPos_ == httpBufLen_) {
// Get more data!
refill();
}
if (readHeaders_) {
readHeaders();
@ -200,10 +202,11 @@ void THttpTransport::refill() {
uint32_t avail = httpBufSize_ - httpBufLen_;
if (avail <= (httpBufSize_ / 4)) {
httpBufSize_ *= 2;
httpBuf_ = (char*)std::realloc(httpBuf_, httpBufSize_ + 1);
if (httpBuf_ == NULL) {
char* tmpBuf = (char*)std::realloc(httpBuf_, httpBufSize_ + 1);
if (tmpBuf == NULL) {
throw std::bad_alloc();
}
httpBuf_ = tmpBuf;
}
// Read more data

View file

@ -36,7 +36,7 @@ namespace transport {
*/
class THttpTransport : public TVirtualTransport<THttpTransport> {
public:
THttpTransport(boost::shared_ptr<TTransport> transport);
THttpTransport(stdcxx::shared_ptr<TTransport> transport);
virtual ~THttpTransport();
@ -59,7 +59,7 @@ public:
virtual const std::string getOrigin();
protected:
boost::shared_ptr<TTransport> transport_;
stdcxx::shared_ptr<TTransport> transport_;
std::string origin_;
TMemoryBuffer writeBuffer_;

View 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.
*/
#include <thrift/transport/TNonblockingSSLServerSocket.h>
#include <thrift/transport/TSSLSocket.h>
namespace apache {
namespace thrift {
namespace transport {
/**
* Nonblocking SSL server socket implementation.
*/
TNonblockingSSLServerSocket::TNonblockingSSLServerSocket(int port, stdcxx::shared_ptr<TSSLSocketFactory> factory)
: TNonblockingServerSocket(port), factory_(factory) {
factory_->server(true);
}
TNonblockingSSLServerSocket::TNonblockingSSLServerSocket(const std::string& address,
int port,
stdcxx::shared_ptr<TSSLSocketFactory> factory)
: TNonblockingServerSocket(address, port), factory_(factory) {
factory_->server(true);
}
TNonblockingSSLServerSocket::TNonblockingSSLServerSocket(int port,
int sendTimeout,
int recvTimeout,
stdcxx::shared_ptr<TSSLSocketFactory> factory)
: TNonblockingServerSocket(port, sendTimeout, recvTimeout), factory_(factory) {
factory_->server(true);
}
stdcxx::shared_ptr<TSocket> TNonblockingSSLServerSocket::createSocket(THRIFT_SOCKET client) {
stdcxx::shared_ptr<TSSLSocket> tSSLSocket;
tSSLSocket = factory_->createSocket(client);
tSSLSocket->setLibeventSafe();
return tSSLSocket;
}
}
}
}

View 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_TRANSPORT_TNONBLOCKINGSSLSERVERSOCKET_H_
#define _THRIFT_TRANSPORT_TNONBLOCKINGSSLSERVERSOCKET_H_ 1
#include <thrift/transport/TNonblockingServerSocket.h>
#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
namespace transport {
class TSSLSocketFactory;
/**
* Nonblocking Server socket that accepts SSL connections.
*/
class TNonblockingSSLServerSocket : public TNonblockingServerSocket {
public:
/**
* Constructor. Binds to all interfaces.
*
* @param port Listening port
* @param factory SSL socket factory implementation
*/
TNonblockingSSLServerSocket(int port, stdcxx::shared_ptr<TSSLSocketFactory> factory);
/**
* Constructor. Binds to the specified address.
*
* @param address Address to bind to
* @param port Listening port
* @param factory SSL socket factory implementation
*/
TNonblockingSSLServerSocket(const std::string& address,
int port,
stdcxx::shared_ptr<TSSLSocketFactory> factory);
/**
* Constructor. Binds to all interfaces.
*
* @param port Listening port
* @param sendTimeout Socket send timeout
* @param recvTimeout Socket receive timeout
* @param factory SSL socket factory implementation
*/
TNonblockingSSLServerSocket(int port,
int sendTimeout,
int recvTimeout,
stdcxx::shared_ptr<TSSLSocketFactory> factory);
protected:
stdcxx::shared_ptr<TSocket> createSocket(THRIFT_SOCKET socket);
stdcxx::shared_ptr<TSSLSocketFactory> factory_;
};
}
}
}
#endif

View file

@ -0,0 +1,548 @@
/*
* 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 <cstring>
#include <stdexcept>
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
#endif
#ifdef HAVE_SYS_POLL_H
#include <sys/poll.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#include <netinet/tcp.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#include <fcntl.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TNonblockingServerSocket.h>
#include <thrift/transport/PlatformSocket.h>
#ifndef AF_LOCAL
#define AF_LOCAL AF_UNIX
#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);
}
namespace apache {
namespace thrift {
namespace transport {
using std::string;
using stdcxx::shared_ptr;
TNonblockingServerSocket::TNonblockingServerSocket(int port)
: port_(port),
listenPort_(port),
serverSocket_(THRIFT_INVALID_SOCKET),
acceptBacklog_(DEFAULT_BACKLOG),
sendTimeout_(0),
recvTimeout_(0),
retryLimit_(0),
retryDelay_(0),
tcpSendBuffer_(0),
tcpRecvBuffer_(0),
keepAlive_(false),
listening_(false) {
}
TNonblockingServerSocket::TNonblockingServerSocket(int port, int sendTimeout, int recvTimeout)
: port_(port),
listenPort_(port),
serverSocket_(THRIFT_INVALID_SOCKET),
acceptBacklog_(DEFAULT_BACKLOG),
sendTimeout_(sendTimeout),
recvTimeout_(recvTimeout),
retryLimit_(0),
retryDelay_(0),
tcpSendBuffer_(0),
tcpRecvBuffer_(0),
keepAlive_(false),
listening_(false) {
}
TNonblockingServerSocket::TNonblockingServerSocket(const string& address, int port)
: port_(port),
listenPort_(port),
address_(address),
serverSocket_(THRIFT_INVALID_SOCKET),
acceptBacklog_(DEFAULT_BACKLOG),
sendTimeout_(0),
recvTimeout_(0),
retryLimit_(0),
retryDelay_(0),
tcpSendBuffer_(0),
tcpRecvBuffer_(0),
keepAlive_(false),
listening_(false) {
}
TNonblockingServerSocket::TNonblockingServerSocket(const string& path)
: port_(0),
listenPort_(0),
path_(path),
serverSocket_(THRIFT_INVALID_SOCKET),
acceptBacklog_(DEFAULT_BACKLOG),
sendTimeout_(0),
recvTimeout_(0),
retryLimit_(0),
retryDelay_(0),
tcpSendBuffer_(0),
tcpRecvBuffer_(0),
keepAlive_(false),
listening_(false) {
}
TNonblockingServerSocket::~TNonblockingServerSocket() {
close();
}
void TNonblockingServerSocket::setSendTimeout(int sendTimeout) {
sendTimeout_ = sendTimeout;
}
void TNonblockingServerSocket::setRecvTimeout(int recvTimeout) {
recvTimeout_ = recvTimeout;
}
void TNonblockingServerSocket::setAcceptBacklog(int accBacklog) {
acceptBacklog_ = accBacklog;
}
void TNonblockingServerSocket::setRetryLimit(int retryLimit) {
retryLimit_ = retryLimit;
}
void TNonblockingServerSocket::setRetryDelay(int retryDelay) {
retryDelay_ = retryDelay;
}
void TNonblockingServerSocket::setTcpSendBuffer(int tcpSendBuffer) {
tcpSendBuffer_ = tcpSendBuffer;
}
void TNonblockingServerSocket::setTcpRecvBuffer(int tcpRecvBuffer) {
tcpRecvBuffer_ = tcpRecvBuffer;
}
void TNonblockingServerSocket::listen() {
listening_ = true;
#ifdef _WIN32
TWinsockSingleton::create();
#endif // _WIN32
// Validate port number
if (port_ < 0 || port_ > 0xFFFF) {
throw TTransportException(TTransportException::BAD_ARGS, "Specified port is invalid");
}
const struct addrinfo *res;
int error;
char port[sizeof("65535")];
THRIFT_SNPRINTF(port, sizeof(port), "%d", port_);
struct addrinfo hints;
std::memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
// If address is not specified use wildcard address (NULL)
TGetAddrInfoWrapper info(address_.empty() ? NULL : &address_[0], port, &hints);
error = info.init();
if (error) {
GlobalOutput.printf("getaddrinfo %d: %s", error, THRIFT_GAI_STRERROR(error));
close();
throw TTransportException(TTransportException::NOT_OPEN,
"Could not resolve host for server socket.");
}
// Pick the ipv6 address first since ipv4 addresses can be mapped
// into ipv6 space.
for (res = info.res(); res; res = res->ai_next) {
if (res->ai_family == AF_INET6 || res->ai_next == NULL)
break;
}
if (!path_.empty()) {
serverSocket_ = socket(PF_UNIX, SOCK_STREAM, IPPROTO_IP);
} else if (res != NULL) {
serverSocket_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
}
if (serverSocket_ == THRIFT_INVALID_SOCKET) {
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TNonblockingServerSocket::listen() socket() ", errno_copy);
close();
throw TTransportException(TTransportException::NOT_OPEN,
"Could not create server socket.",
errno_copy);
}
// Set THRIFT_NO_SOCKET_CACHING to prevent 2MSL delay on accept
int one = 1;
if (-1 == setsockopt(serverSocket_,
SOL_SOCKET,
THRIFT_NO_SOCKET_CACHING,
cast_sockopt(&one),
sizeof(one))) {
// ignore errors coming out of this setsockopt on Windows. This is because
// SO_EXCLUSIVEADDRUSE requires admin privileges on WinXP, but we don't
// want to force servers to be an admin.
#ifndef _WIN32
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TNonblockingServerSocket::listen() setsockopt() THRIFT_NO_SOCKET_CACHING ",
errno_copy);
close();
throw TTransportException(TTransportException::NOT_OPEN,
"Could not set THRIFT_NO_SOCKET_CACHING",
errno_copy);
#endif
}
// Set TCP buffer sizes
if (tcpSendBuffer_ > 0) {
if (-1 == setsockopt(serverSocket_,
SOL_SOCKET,
SO_SNDBUF,
cast_sockopt(&tcpSendBuffer_),
sizeof(tcpSendBuffer_))) {
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TNonblockingServerSocket::listen() setsockopt() SO_SNDBUF ", errno_copy);
close();
throw TTransportException(TTransportException::NOT_OPEN,
"Could not set SO_SNDBUF",
errno_copy);
}
}
if (tcpRecvBuffer_ > 0) {
if (-1 == setsockopt(serverSocket_,
SOL_SOCKET,
SO_RCVBUF,
cast_sockopt(&tcpRecvBuffer_),
sizeof(tcpRecvBuffer_))) {
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TNonblockingServerSocket::listen() setsockopt() SO_RCVBUF ", errno_copy);
close();
throw TTransportException(TTransportException::NOT_OPEN,
"Could not set SO_RCVBUF",
errno_copy);
}
}
#ifdef IPV6_V6ONLY
if (res->ai_family == AF_INET6 && path_.empty()) {
int zero = 0;
if (-1 == setsockopt(serverSocket_,
IPPROTO_IPV6,
IPV6_V6ONLY,
cast_sockopt(&zero),
sizeof(zero))) {
GlobalOutput.perror("TNonblockingServerSocket::listen() IPV6_V6ONLY ", THRIFT_GET_SOCKET_ERROR);
}
}
#endif // #ifdef IPV6_V6ONLY
// Turn linger off, don't want to block on calls to close
struct linger ling = {0, 0};
if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_LINGER, cast_sockopt(&ling), sizeof(ling))) {
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TNonblockingServerSocket::listen() setsockopt() SO_LINGER ", errno_copy);
close();
throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_LINGER", errno_copy);
}
// Keepalive to ensure full result flushing
if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_KEEPALIVE, const_cast_sockopt(&one), sizeof(one))) {
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TNonblockingServerSocket::listen() setsockopt() SO_KEEPALIVE ", errno_copy);
close();
throw TTransportException(TTransportException::NOT_OPEN,
"Could not set TCP_NODELAY",
errno_copy);
}
// Set TCP nodelay if available, MAC OS X Hack
// See http://lists.danga.com/pipermail/memcached/2005-March/001240.html
#ifndef TCP_NOPUSH
// Unix Sockets do not need that
if (path_.empty()) {
// TCP Nodelay, speed over bandwidth
if (-1
== setsockopt(serverSocket_, IPPROTO_TCP, TCP_NODELAY, cast_sockopt(&one), sizeof(one))) {
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TNonblockingServerSocket::listen() setsockopt() TCP_NODELAY ", errno_copy);
close();
throw TTransportException(TTransportException::NOT_OPEN,
"Could not set TCP_NODELAY",
errno_copy);
}
}
#endif
// Set NONBLOCK on the accept socket
int flags = THRIFT_FCNTL(serverSocket_, THRIFT_F_GETFL, 0);
if (flags == -1) {
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TNonblockingServerSocket::listen() THRIFT_FCNTL() THRIFT_F_GETFL ", errno_copy);
close();
throw TTransportException(TTransportException::NOT_OPEN,
"THRIFT_FCNTL() THRIFT_F_GETFL failed",
errno_copy);
}
if (-1 == THRIFT_FCNTL(serverSocket_, THRIFT_F_SETFL, flags | THRIFT_O_NONBLOCK)) {
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TNonblockingServerSocket::listen() THRIFT_FCNTL() THRIFT_O_NONBLOCK ", errno_copy);
close();
throw TTransportException(TTransportException::NOT_OPEN,
"THRIFT_FCNTL() THRIFT_F_SETFL THRIFT_O_NONBLOCK failed",
errno_copy);
}
#ifdef TCP_LOW_MIN_RTO
if (TSocket::getUseLowMinRto()) {
if (-1 == setsockopt(s, IPPROTO_TCP, TCP_LOW_MIN_RTO, const_cast_sockopt(&one), sizeof(one))) {
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TNonblockingServerSocket::listen() setsockopt() TCP_LOW_MIN_RTO ", errno_copy);
close();
throw TTransportException(TTransportException::NOT_OPEN,
"Could not set TCP_NODELAY",
errno_copy);
}
}
#endif
// prepare the port information
// we may want to try to bind more than once, since THRIFT_NO_SOCKET_CACHING doesn't
// always seem to work. The client can configure the retry variables.
int retries = 0;
int errno_copy = 0;
if (!path_.empty()) {
#ifndef _WIN32
// Unix Domain Socket
size_t len = path_.size() + 1;
if (len > sizeof(((sockaddr_un*)NULL)->sun_path)) {
errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TSocket::listen() Unix Domain socket path too long", errno_copy);
throw TTransportException(TTransportException::NOT_OPEN,
"Unix Domain socket path too long",
errno_copy);
}
struct sockaddr_un address;
address.sun_family = AF_UNIX;
memcpy(address.sun_path, path_.c_str(), len);
socklen_t structlen = static_cast<socklen_t>(sizeof(address));
if (!address.sun_path[0]) { // abstract namespace socket
#ifdef __linux__
// sun_path is not null-terminated in this case and structlen determines its length
structlen -= sizeof(address.sun_path) - len;
#else
GlobalOutput.perror("TSocket::open() Abstract Namespace Domain sockets only supported on linux: ", -99);
throw TTransportException(TTransportException::NOT_OPEN,
" Abstract Namespace Domain socket path not supported");
#endif
}
do {
if (0 == ::bind(serverSocket_, (struct sockaddr*)&address, structlen)) {
break;
}
errno_copy = THRIFT_GET_SOCKET_ERROR;
// use short circuit evaluation here to only sleep if we need to
} while ((retries++ < retryLimit_) && (THRIFT_SLEEP_SEC(retryDelay_) == 0));
#else
GlobalOutput.perror("TSocket::open() Unix Domain socket path not supported on windows", -99);
throw TTransportException(TTransportException::NOT_OPEN,
" Unix Domain socket path not supported");
#endif
} else {
do {
if (0 == ::bind(serverSocket_, res->ai_addr, static_cast<int>(res->ai_addrlen))) {
break;
}
errno_copy = THRIFT_GET_SOCKET_ERROR;
// use short circuit evaluation here to only sleep if we need to
} while ((retries++ < retryLimit_) && (THRIFT_SLEEP_SEC(retryDelay_) == 0));
// retrieve bind info
if (port_ == 0 && retries <= retryLimit_) {
struct sockaddr_storage sa;
socklen_t len = sizeof(sa);
std::memset(&sa, 0, len);
if (::getsockname(serverSocket_, reinterpret_cast<struct sockaddr*>(&sa), &len) < 0) {
errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TNonblockingServerSocket::getPort() getsockname() ", errno_copy);
} else {
if (sa.ss_family == AF_INET6) {
const struct sockaddr_in6* sin = reinterpret_cast<const struct sockaddr_in6*>(&sa);
listenPort_ = ntohs(sin->sin6_port);
} else {
const struct sockaddr_in* sin = reinterpret_cast<const struct sockaddr_in*>(&sa);
listenPort_ = ntohs(sin->sin_port);
}
}
}
}
// throw an error if we failed to bind properly
if (retries > retryLimit_) {
char errbuf[1024];
if (!path_.empty()) {
THRIFT_SNPRINTF(errbuf, sizeof(errbuf), "TNonblockingServerSocket::listen() PATH %s", path_.c_str());
} else {
THRIFT_SNPRINTF(errbuf, sizeof(errbuf), "TNonblockingServerSocket::listen() BIND %d", port_);
}
GlobalOutput(errbuf);
close();
throw TTransportException(TTransportException::NOT_OPEN,
"Could not bind",
errno_copy);
}
if (listenCallback_)
listenCallback_(serverSocket_);
// Call listen
if (-1 == ::listen(serverSocket_, acceptBacklog_)) {
errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TNonblockingServerSocket::listen() listen() ", errno_copy);
close();
throw TTransportException(TTransportException::NOT_OPEN, "Could not listen", errno_copy);
}
// The socket is now listening!
}
int TNonblockingServerSocket::getPort() {
return port_;
}
int TNonblockingServerSocket::getListenPort() {
return listenPort_;
}
shared_ptr<TSocket> TNonblockingServerSocket::acceptImpl() {
if (serverSocket_ == THRIFT_INVALID_SOCKET) {
throw TTransportException(TTransportException::NOT_OPEN, "TNonblockingServerSocket not listening");
}
struct sockaddr_storage clientAddress;
int size = sizeof(clientAddress);
THRIFT_SOCKET clientSocket
= ::accept(serverSocket_, (struct sockaddr*)&clientAddress, (socklen_t*)&size);
if (clientSocket == THRIFT_INVALID_SOCKET) {
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TNonblockingServerSocket::acceptImpl() ::accept() ", errno_copy);
throw TTransportException(TTransportException::UNKNOWN, "accept()", errno_copy);
}
// Explicitly set this socket to NONBLOCK mode
int flags = THRIFT_FCNTL(clientSocket, THRIFT_F_GETFL, 0);
if (flags == -1) {
int errno_copy = THRIFT_GET_SOCKET_ERROR;
::THRIFT_CLOSESOCKET(clientSocket);
GlobalOutput.perror("TNonblockingServerSocket::acceptImpl() THRIFT_FCNTL() THRIFT_F_GETFL ", errno_copy);
throw TTransportException(TTransportException::UNKNOWN,
"THRIFT_FCNTL(THRIFT_F_GETFL)",
errno_copy);
}
if (-1 == THRIFT_FCNTL(clientSocket, THRIFT_F_SETFL, flags | THRIFT_O_NONBLOCK)) {
int errno_copy = THRIFT_GET_SOCKET_ERROR;
::THRIFT_CLOSESOCKET(clientSocket);
GlobalOutput
.perror("TNonblockingServerSocket::acceptImpl() THRIFT_FCNTL() THRIFT_F_SETFL ~THRIFT_O_NONBLOCK ",
errno_copy);
throw TTransportException(TTransportException::UNKNOWN,
"THRIFT_FCNTL(THRIFT_F_SETFL)",
errno_copy);
}
shared_ptr<TSocket> client = createSocket(clientSocket);
if (sendTimeout_ > 0) {
client->setSendTimeout(sendTimeout_);
}
if (recvTimeout_ > 0) {
client->setRecvTimeout(recvTimeout_);
}
if (keepAlive_) {
client->setKeepAlive(keepAlive_);
}
client->setCachedAddress((sockaddr*)&clientAddress, size);
if (acceptCallback_)
acceptCallback_(clientSocket);
return client;
}
shared_ptr<TSocket> TNonblockingServerSocket::createSocket(THRIFT_SOCKET clientSocket) {
return shared_ptr<TSocket>(new TSocket(clientSocket));
}
void TNonblockingServerSocket::close() {
if (serverSocket_ != THRIFT_INVALID_SOCKET) {
shutdown(serverSocket_, THRIFT_SHUT_RDWR);
::THRIFT_CLOSESOCKET(serverSocket_);
}
serverSocket_ = THRIFT_INVALID_SOCKET;
listening_ = false;
}
}
}
} // apache::thrift::transport

View file

@ -0,0 +1,137 @@
/*
* 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_TRANSPORT_TNONBLOCKINGSERVERSOCKET_H_
#define _THRIFT_TRANSPORT_TNONBLOCKINGSERVERSOCKET_H_ 1
#include <thrift/transport/TNonblockingServerTransport.h>
#include <thrift/transport/PlatformSocket.h>
#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
namespace transport {
class TSocket;
/**
* Nonblocking Server socket implementation of TNonblockingServerTransport. Wrapper around a unix
* socket listen and accept calls.
*
*/
class TNonblockingServerSocket : public TNonblockingServerTransport {
public:
typedef apache::thrift::stdcxx::function<void(THRIFT_SOCKET fd)> socket_func_t;
const static int DEFAULT_BACKLOG = 1024;
/**
* Constructor.
*
* @param port Port number to bind to
*/
TNonblockingServerSocket(int port);
/**
* Constructor.
*
* @param port Port number to bind to
* @param sendTimeout Socket send timeout
* @param recvTimeout Socket receive timeout
*/
TNonblockingServerSocket(int port, int sendTimeout, int recvTimeout);
/**
* Constructor.
*
* @param address Address to bind to
* @param port Port number to bind to
*/
TNonblockingServerSocket(const std::string& address, int port);
/**
* Constructor used for unix sockets.
*
* @param path Pathname for unix socket.
*/
TNonblockingServerSocket(const std::string& path);
virtual ~TNonblockingServerSocket();
void setSendTimeout(int sendTimeout);
void setRecvTimeout(int recvTimeout);
void setAcceptBacklog(int accBacklog);
void setRetryLimit(int retryLimit);
void setRetryDelay(int retryDelay);
void setKeepAlive(bool keepAlive) { keepAlive_ = keepAlive; }
void setTcpSendBuffer(int tcpSendBuffer);
void setTcpRecvBuffer(int tcpRecvBuffer);
// listenCallback gets called just before listen, and after all Thrift
// setsockopt calls have been made. If you have custom setsockopt
// things that need to happen on the listening socket, this is the place to do it.
void setListenCallback(const socket_func_t& listenCallback) { listenCallback_ = listenCallback; }
// acceptCallback gets called after each accept call, on the newly created socket.
// It is called after all Thrift setsockopt calls have been made. If you have
// custom setsockopt things that need to happen on the accepted
// socket, this is the place to do it.
void setAcceptCallback(const socket_func_t& acceptCallback) { acceptCallback_ = acceptCallback; }
THRIFT_SOCKET getSocketFD() { return serverSocket_; }
int getPort();
int getListenPort();
void listen();
void close();
protected:
apache::thrift::stdcxx::shared_ptr<TSocket> acceptImpl();
virtual apache::thrift::stdcxx::shared_ptr<TSocket> createSocket(THRIFT_SOCKET client);
private:
int port_;
int listenPort_;
std::string address_;
std::string path_;
THRIFT_SOCKET serverSocket_;
int acceptBacklog_;
int sendTimeout_;
int recvTimeout_;
int retryLimit_;
int retryDelay_;
int tcpSendBuffer_;
int tcpRecvBuffer_;
bool keepAlive_;
bool listening_;
socket_func_t listenCallback_;
socket_func_t acceptCallback_;
};
}
}
} // apache::thrift::transport
#endif // #ifndef _THRIFT_TRANSPORT_TNONBLOCKINGSERVERSOCKET_H_

View 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_TRANSPORT_TNONBLOCKINGSERVERTRANSPORT_H_
#define _THRIFT_TRANSPORT_TNONBLOCKINGSERVERTRANSPORT_H_ 1
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportException.h>
#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
namespace transport {
/**
* Server transport framework. A server needs to have some facility for
* creating base transports to read/write from. The server is expected
* to keep track of TTransport children that it creates for purposes of
* controlling their lifetime.
*/
class TNonblockingServerTransport {
public:
virtual ~TNonblockingServerTransport() {}
/**
* Starts the server transport listening for new connections. Prior to this
* call most transports will not return anything when accept is called.
*
* @throws TTransportException if we were unable to listen
*/
virtual void listen() {}
/**
* Gets a new dynamically allocated transport object and passes it to the
* caller. Note that it is the explicit duty of the caller to free the
* allocated object. The returned TTransport object must always be in the
* opened state. NULL should never be returned, instead an Exception should
* always be thrown.
*
* @return A new TTransport object
* @throws TTransportException if there is an error
*/
stdcxx::shared_ptr<TSocket> accept() {
stdcxx::shared_ptr<TSocket> result = acceptImpl();
if (!result) {
throw TTransportException("accept() may not return NULL");
}
return result;
}
/**
* Utility method
*
* @return server socket file descriptor
* @throw TTransportException If an error occurs
*/
virtual THRIFT_SOCKET getSocketFD() = 0;
virtual int getPort() = 0;
virtual int getListenPort() = 0;
/**
* Closes this transport such that future calls to accept will do nothing.
*/
virtual void close() = 0;
protected:
TNonblockingServerTransport() {}
/**
* Subclasses should implement this function for accept.
*
* @return A newly allocated TTransport object
* @throw TTransportException If an error occurs
*/
virtual stdcxx::shared_ptr<TSocket> acceptImpl() = 0;
};
}
}
} // apache::thrift::transport
#endif // #ifndef _THRIFT_TRANSPORT_TNONBLOCKINGSERVERTRANSPORT_H_

View file

@ -28,8 +28,6 @@ namespace apache {
namespace thrift {
namespace transport {
using namespace std;
/**
* TPipe implementation.
*/
@ -160,7 +158,8 @@ uint32_t TWaitableNamedPipeImpl::read(uint8_t* buf, uint32_t len) {
end_unread_idx_ = endAsyncRead();
}
uint32_t bytes_to_copy = (std::min)(len, end_unread_idx_ - begin_unread_idx_);
uint32_t __idxsize = end_unread_idx_ - begin_unread_idx_;
uint32_t bytes_to_copy = (len < __idxsize) ? len : __idxsize;
memcpy(buf, &buffer_[begin_unread_idx_], bytes_to_copy);
begin_unread_idx_ += bytes_to_copy;
if (begin_unread_idx_ != end_unread_idx_) {
@ -341,12 +340,12 @@ void pipe_write(HANDLE pipe, const uint8_t* buf, uint32_t len) {
// Accessors
//---------------------------------------------------------
string TPipe::getPipename() {
std::string TPipe::getPipename() {
return pipename_;
}
void TPipe::setPipename(const std::string& pipename) {
if (pipename.find("\\\\") == -1)
if (pipename.find("\\\\") == std::string::npos)
pipename_ = "\\\\.\\pipe\\" + pipename;
else
pipename_ = pipename;

View file

@ -95,7 +95,7 @@ public:
HANDLE getNativeWaitHandle();
private:
boost::shared_ptr<TPipeImpl> impl_;
stdcxx::shared_ptr<TPipeImpl> impl_;
std::string pipename_;

View file

@ -22,7 +22,7 @@
#include <thrift/transport/TPipe.h>
#include <thrift/transport/TPipeServer.h>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
#include <boost/noncopyable.hpp>
#ifdef _WIN32
@ -37,15 +37,14 @@ namespace transport {
#ifdef _WIN32
using namespace std;
using boost::shared_ptr;
using stdcxx::shared_ptr;
class TPipeServerImpl : boost::noncopyable {
public:
TPipeServerImpl() {}
virtual ~TPipeServerImpl() {}
virtual void interrupt() = 0;
virtual boost::shared_ptr<TTransport> acceptImpl() = 0;
virtual stdcxx::shared_ptr<TTransport> acceptImpl() = 0;
virtual HANDLE getPipeHandle() = 0;
virtual HANDLE getWrtPipeHandle() = 0;
@ -76,7 +75,7 @@ public:
virtual void interrupt() {} // not currently implemented
virtual boost::shared_ptr<TTransport> acceptImpl();
virtual stdcxx::shared_ptr<TTransport> acceptImpl();
virtual HANDLE getPipeHandle() { return PipeR_.h; }
virtual HANDLE getWrtPipeHandle() { return PipeW_.h; }
@ -118,7 +117,7 @@ public:
}
}
virtual boost::shared_ptr<TTransport> acceptImpl();
virtual stdcxx::shared_ptr<TTransport> acceptImpl();
virtual HANDLE getPipeHandle() { return Pipe_.h; }
virtual HANDLE getWrtPipeHandle() { return INVALID_HANDLE_VALUE; }
@ -142,7 +141,7 @@ private:
TCriticalSection pipe_protect_;
// only read or write these variables underneath a locked pipe_protect_
boost::shared_ptr<TPipe> cached_client_;
stdcxx::shared_ptr<TPipe> cached_client_;
TAutoHandle Pipe_;
};
@ -297,6 +296,10 @@ shared_ptr<TTransport> TNamedPipeServer::acceptImpl() {
// if we got here, then we are in an error / shutdown case
DWORD gle = GetLastError(); // save error before doing cleanup
GlobalOutput.perror("TPipeServer ConnectNamedPipe GLE=", gle);
if(gle == ERROR_OPERATION_ABORTED) {
TAutoCrit lock(pipe_protect_); // Needed to insure concurrent thread to be out of interrupt.
throw TTransportException(TTransportException::INTERRUPTED, "TPipeServer: server interupted");
}
throw TTransportException(TTransportException::NOT_OPEN, "TPipeServer: client connection failed");
}
@ -361,7 +364,7 @@ bool TNamedPipeServer::createNamedPipe(const TAutoCrit & /*lockProof*/) {
GlobalOutput.perror("TPipeServer::TCreateNamedPipe() GLE=", lastError);
throw TTransportException(TTransportException::NOT_OPEN,
"TCreateNamedPipe() failed",
lastError);
lastError);
return false;
}
@ -404,12 +407,12 @@ bool TAnonPipeServer::createAnonPipe() {
//---------------------------------------------------------
// Accessors
//---------------------------------------------------------
string TPipeServer::getPipename() {
std::string TPipeServer::getPipename() {
return pipename_;
}
void TPipeServer::setPipename(const std::string& pipename) {
if (pipename.find("\\\\") == -1)
if (pipename.find("\\\\") == std::string::npos)
pipename_ = "\\\\.\\pipe\\" + pipename;
else
pipename_ = pipename;

View file

@ -21,7 +21,7 @@
#define _THRIFT_TRANSPORT_TSERVERWINPIPES_H_ 1
#include <thrift/transport/TServerTransport.h>
#include <boost/shared_ptr.hpp>
#include <thrift/stdcxx.h>
#ifndef _WIN32
#include <thrift/transport/TServerSocket.h>
#endif
@ -82,10 +82,10 @@ public:
HANDLE getNativeWaitHandle();
protected:
virtual boost::shared_ptr<TTransport> acceptImpl();
virtual stdcxx::shared_ptr<TTransport> acceptImpl();
private:
boost::shared_ptr<TPipeServerImpl> impl_;
stdcxx::shared_ptr<TPipeServerImpl> impl_;
std::string pipename_;
uint32_t bufsize_;

Some files were not shown because too many files have changed in this diff Show more