You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by sm...@apache.org on 2014/07/12 06:08:30 UTC
[12/47] Added c++ client samples for integrattion of airavata with
any other application's c++ interface
http://git-wip-us.apache.org/repos/asf/airavata/blob/f891b7dc/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/TReflectionLocal.h
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/TReflectionLocal.h b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/TReflectionLocal.h
new file mode 100644
index 0000000..2ef7511
--- /dev/null
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/TReflectionLocal.h
@@ -0,0 +1,96 @@
+/*
+ * 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_TREFLECTIONLOCAL_H_
+#define _THRIFT_TREFLECTIONLOCAL_H_ 1
+
+#include <stdint.h>
+#include <cstring>
+#include <thrift/protocol/TProtocol.h>
+
+/**
+ * Local Reflection is a blanket term referring to the the structure
+ * and generation of this particular representation of Thrift types.
+ * (It is called local because it cannot be serialized by Thrift).
+ *
+ */
+
+namespace apache { namespace thrift { namespace reflection { namespace local {
+
+using apache::thrift::protocol::TType;
+
+// We include this many bytes of the structure's fingerprint when serializing
+// a top-level structure. Long enough to make collisions unlikely, short
+// enough to not significantly affect the amount of memory used.
+const int FP_PREFIX_LEN = 4;
+
+struct FieldMeta {
+ int16_t tag;
+ bool is_optional;
+};
+
+struct TypeSpec {
+ TType ttype;
+ uint8_t fp_prefix[FP_PREFIX_LEN];
+
+ // Use an anonymous union here so we can fit two TypeSpecs in one cache line.
+ union {
+ struct {
+ // Use parallel arrays here for denser packing (of the arrays).
+ FieldMeta* metas;
+ TypeSpec** specs;
+ } tstruct;
+ struct {
+ TypeSpec *subtype1;
+ TypeSpec *subtype2;
+ } tcontainer;
+ };
+
+ // Static initialization of unions isn't really possible,
+ // so take the plunge and use constructors.
+ // Hopefully they'll be evaluated at compile time.
+
+ TypeSpec(TType ttype) : ttype(ttype) {
+ std::memset(fp_prefix, 0, FP_PREFIX_LEN);
+ }
+
+ TypeSpec(TType ttype,
+ const uint8_t* fingerprint,
+ FieldMeta* metas,
+ TypeSpec** specs) :
+ ttype(ttype)
+ {
+ std::memcpy(fp_prefix, fingerprint, FP_PREFIX_LEN);
+ tstruct.metas = metas;
+ tstruct.specs = specs;
+ }
+
+ TypeSpec(TType ttype, TypeSpec* subtype1, TypeSpec* subtype2) :
+ ttype(ttype)
+ {
+ std::memset(fp_prefix, 0, FP_PREFIX_LEN);
+ tcontainer.subtype1 = subtype1;
+ tcontainer.subtype2 = subtype2;
+ }
+
+};
+
+}}}} // apache::thrift::reflection::local
+
+#endif // #ifndef _THRIFT_TREFLECTIONLOCAL_H_
http://git-wip-us.apache.org/repos/asf/airavata/blob/f891b7dc/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/Thrift.cpp
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/Thrift.cpp b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/Thrift.cpp
new file mode 100644
index 0000000..b1e1386
--- /dev/null
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/Thrift.cpp
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <thrift/Thrift.h>
+#include <cstring>
+#include <cstdlib>
+#include <boost/lexical_cast.hpp>
+#include <stdarg.h>
+#include <stdio.h>
+
+namespace apache { namespace thrift {
+
+TOutput GlobalOutput;
+
+void TOutput::printf(const char *message, ...) {
+#ifndef THRIFT_SQUELCH_CONSOLE_OUTPUT
+ // Try to reduce heap usage, even if printf is called rarely.
+ static const int STACK_BUF_SIZE = 256;
+ char stack_buf[STACK_BUF_SIZE];
+ va_list ap;
+
+#ifdef _MSC_VER
+ va_start(ap, message);
+ int need = _vscprintf(message, ap);
+ va_end(ap);
+
+ if (need < STACK_BUF_SIZE) {
+ va_start(ap, message);
+ vsnprintf_s(stack_buf, STACK_BUF_SIZE, _TRUNCATE, message, ap);
+ va_end(ap);
+ f_(stack_buf);
+ return;
+ }
+#else
+ va_start(ap, message);
+ int need = vsnprintf(stack_buf, STACK_BUF_SIZE, message, ap);
+ va_end(ap);
+
+ if (need < STACK_BUF_SIZE) {
+ f_(stack_buf);
+ return;
+ }
+#endif
+
+ char *heap_buf = (char*)malloc((need+1) * sizeof(char));
+ if (heap_buf == NULL) {
+#ifdef _MSC_VER
+ va_start(ap, message);
+ vsnprintf_s(stack_buf, STACK_BUF_SIZE, _TRUNCATE, message, ap);
+ va_end(ap);
+#endif
+ // Malloc failed. We might as well print the stack buffer.
+ f_(stack_buf);
+ return;
+ }
+
+ va_start(ap, message);
+ int rval = vsnprintf(heap_buf, need+1, message, ap);
+ va_end(ap);
+ // TODO(shigin): inform user
+ if (rval != -1) {
+ f_(heap_buf);
+ }
+ free(heap_buf);
+#endif
+}
+
+void TOutput::errorTimeWrapper(const char* msg) {
+#ifndef THRIFT_SQUELCH_CONSOLE_OUTPUT
+ time_t now;
+ char dbgtime[26];
+ time(&now);
+ THRIFT_CTIME_R(&now, dbgtime);
+ dbgtime[24] = 0;
+ fprintf(stderr, "Thrift: %s %s\n", dbgtime, msg);
+#endif
+}
+
+void TOutput::perror(const char *message, int errno_copy) {
+ std::string out = message + strerror_s(errno_copy);
+ f_(out.c_str());
+}
+
+std::string TOutput::strerror_s(int errno_copy) {
+#ifndef HAVE_STRERROR_R
+ return "errno = " + boost::lexical_cast<std::string>(errno_copy);
+#else // HAVE_STRERROR_R
+
+ char b_errbuf[1024] = { '\0' };
+#ifdef STRERROR_R_CHAR_P
+ char *b_error = strerror_r(errno_copy, b_errbuf, sizeof(b_errbuf));
+#else
+ char *b_error = b_errbuf;
+ int rv = strerror_r(errno_copy, b_errbuf, sizeof(b_errbuf));
+ if (rv == -1) {
+ // strerror_r failed. omgwtfbbq.
+ return "XSI-compliant strerror_r() failed with errno = " +
+ boost::lexical_cast<std::string>(errno_copy);
+ }
+#endif
+ // Can anyone prove that explicit cast is probably not necessary
+ // to ensure that the string object is constructed before
+ // b_error becomes invalid?
+ return std::string(b_error);
+
+#endif // HAVE_STRERROR_R
+}
+
+}} // apache::thrift
http://git-wip-us.apache.org/repos/asf/airavata/blob/f891b7dc/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/Thrift.h
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/Thrift.h b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/Thrift.h
new file mode 100644
index 0000000..03caa9e
--- /dev/null
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/Thrift.h
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _THRIFT_THRIFT_H_
+#define _THRIFT_THRIFT_H_ 1
+
+#include <thrift/transport/PlatformSocket.h>
+
+#include <thrift/thrift-config.h>
+
+#include <stdio.h>
+#include <assert.h>
+
+#include <sys/types.h>
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#include <string>
+#include <map>
+#include <list>
+#include <set>
+#include <vector>
+#include <exception>
+#include <typeinfo>
+
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+
+#include <thrift/TLogging.h>
+
+/**
+ * Helper macros to allow function overloading even when using
+ * boost::shared_ptr.
+ *
+ * shared_ptr makes overloading really annoying, since shared_ptr defines
+ * constructor methods to allow one shared_ptr type to be constructed from any
+ * other shared_ptr type. (Even if it would be a compile error to actually try
+ * to instantiate the constructor.) These macros add an extra argument to the
+ * function to cause it to only be instantiated if a pointer of type T is
+ * convertible to a pointer of type U.
+ *
+ * THRIFT_OVERLOAD_IF should be used in function declarations.
+ * THRIFT_OVERLOAD_IF_DEFN should be used in the function definition, if it is
+ * defined separately from where it is declared.
+ */
+#define THRIFT_OVERLOAD_IF_DEFN(T, Y) \
+ typename ::boost::enable_if<typename ::boost::is_convertible<T*, Y*>::type, \
+ void*>::type
+
+#define THRIFT_OVERLOAD_IF(T, Y) \
+ THRIFT_OVERLOAD_IF_DEFN(T, Y) = NULL
+
+#define THRIFT_UNUSED_VARIABLE(x) ((x)=(x))
+
+namespace apache { namespace thrift {
+
+class TEnumIterator : public std::iterator<std::forward_iterator_tag, std::pair<int, const char*> > {
+ public:
+ TEnumIterator(int n,
+ int* enums,
+ const char** names) :
+ ii_(0), n_(n), enums_(enums), names_(names) {
+ }
+
+ int operator ++() {
+ return ++ii_;
+ }
+
+ bool operator !=(const TEnumIterator& end) {
+ assert(end.n_ == -1);
+ return (ii_ != n_);
+ }
+
+ std::pair<int, const char*> operator*() const {
+ return std::make_pair(enums_[ii_], names_[ii_]);
+ }
+
+ private:
+ int ii_;
+ const int n_;
+ int* enums_;
+ const char** names_;
+};
+
+class TOutput {
+ public:
+ TOutput() : f_(&errorTimeWrapper) {}
+
+ inline void setOutputFunction(void (*function)(const char *)){
+ f_ = function;
+ }
+
+ inline void operator()(const char *message){
+ f_(message);
+ }
+
+ // It is important to have a const char* overload here instead of
+ // just the string version, otherwise errno could be corrupted
+ // if there is some problem allocating memory when constructing
+ // the string.
+ void perror(const char *message, int errno_copy);
+ inline void perror(const std::string &message, int errno_copy) {
+ perror(message.c_str(), errno_copy);
+ }
+
+ void printf(const char *message, ...);
+
+ static void errorTimeWrapper(const char* msg);
+
+ /** Just like strerror_r but returns a C++ string object. */
+ static std::string strerror_s(int errno_copy);
+
+ private:
+ void (*f_)(const char *);
+};
+
+extern TOutput GlobalOutput;
+
+class TException : public std::exception {
+ public:
+ TException():
+ message_() {}
+
+ TException(const std::string& message) :
+ message_(message) {}
+
+ virtual ~TException() throw() {}
+
+ virtual const char* what() const throw() {
+ if (message_.empty()) {
+ return "Default TException.";
+ } else {
+ return message_.c_str();
+ }
+ }
+
+ protected:
+ std::string message_;
+
+};
+
+
+// Forward declare this structure used by TDenseProtocol
+namespace reflection { namespace local {
+struct TypeSpec;
+}}
+
+class TDelayedException {
+ public:
+ template <class E> static TDelayedException* delayException(const E& e);
+ virtual void throw_it() = 0;
+ virtual ~TDelayedException() {};
+};
+
+template <class E> class TExceptionWrapper : public TDelayedException {
+ public:
+ TExceptionWrapper(const E& e) : e_(e) {}
+ virtual void throw_it() {
+ E temp(e_);
+ delete this;
+ throw temp;
+ }
+ private:
+ E e_;
+};
+
+template <class E>
+TDelayedException* TDelayedException::delayException(const E& e) {
+ return new TExceptionWrapper<E>(e);
+}
+
+#if T_GLOBAL_DEBUG_VIRTUAL > 1
+void profile_virtual_call(const std::type_info& info);
+void profile_generic_protocol(const std::type_info& template_type,
+ const std::type_info& prot_type);
+void profile_print_info(FILE *f);
+void profile_print_info();
+void profile_write_pprof(FILE* gen_calls_f, FILE* virtual_calls_f);
+#endif
+
+}} // apache::thrift
+
+#endif // #ifndef _THRIFT_THRIFT_H_
http://git-wip-us.apache.org/repos/asf/airavata/blob/f891b7dc/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/VirtualProfiling.cpp
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/VirtualProfiling.cpp b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/VirtualProfiling.cpp
new file mode 100644
index 0000000..180cfb7
--- /dev/null
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/VirtualProfiling.cpp
@@ -0,0 +1,455 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <thrift/Thrift.h>
+
+// Do nothing if virtual call profiling is not enabled
+#if T_GLOBAL_DEBUG_VIRTUAL > 1
+
+// TODO: This code only works with g++ (since we rely on the fact
+// that all std::type_info instances referring to a particular type
+// always return the exact same pointer value from name().)
+#ifndef __GNUG__
+#error "Thrift virtual function profiling currently only works with gcc"
+#endif // !__GNUG__
+
+// TODO: We also require glibc for the backtrace() and backtrace_symbols()
+// functions.
+#ifndef __GLIBC__
+#error "Thrift virtual function profiling currently requires glibc"
+#endif // !__GLIBC__
+
+
+#include <thrift/concurrency/Mutex.h>
+
+#include <ext/hash_map>
+#include <execinfo.h>
+#include <stdio.h>
+
+namespace apache { namespace thrift {
+
+using ::apache::thrift::concurrency::Mutex;
+using ::apache::thrift::concurrency::Guard;
+
+static const unsigned int MAX_STACK_DEPTH = 15;
+
+/**
+ * A stack trace
+ */
+class Backtrace {
+ public:
+ Backtrace(int skip = 0);
+ Backtrace(Backtrace const &bt);
+
+ void operator=(Backtrace const &bt) {
+ numCallers_ = bt.numCallers_;
+ if (numCallers_ >= 0) {
+ memcpy(callers_, bt.callers_, numCallers_ * sizeof(void*));
+ }
+ }
+
+ bool operator==(Backtrace const &bt) const {
+ return (cmp(bt) == 0);
+ }
+
+ size_t hash() const {
+ intptr_t ret = 0;
+ for (int n = 0; n < numCallers_; ++n) {
+ ret ^= reinterpret_cast<intptr_t>(callers_[n]);
+ }
+ return static_cast<size_t>(ret);
+ }
+
+ int cmp(Backtrace const& bt) const {
+ int depth_diff = (numCallers_ - bt.numCallers_);
+ if (depth_diff != 0) {
+ return depth_diff;
+ }
+
+ for (int n = 0; n < numCallers_; ++n) {
+ int diff = reinterpret_cast<intptr_t>(callers_[n]) -
+ reinterpret_cast<intptr_t>(bt.callers_[n]);
+ if (diff != 0) {
+ return diff;
+ }
+ }
+
+ return 0;
+ }
+
+ void print(FILE *f, int indent=0, int start=0) const {
+ char **strings = backtrace_symbols(callers_, numCallers_);
+ if (strings) {
+ start += skip_;
+ if (start < 0) {
+ start = 0;
+ }
+ for (int n = start; n < numCallers_; ++n) {
+ fprintf(f, "%*s#%-2d %s\n", indent, "", n, strings[n]);
+ }
+ free(strings);
+ } else {
+ fprintf(f, "%*s<failed to determine symbols>\n", indent, "");
+ }
+ }
+
+ int getDepth() const {
+ return numCallers_ - skip_;
+ }
+
+ void *getFrame(int index) const {
+ int adjusted_index = index + skip_;
+ if (adjusted_index < 0 || adjusted_index >= numCallers_) {
+ return NULL;
+ }
+ return callers_[adjusted_index];
+ }
+
+ private:
+ void *callers_[MAX_STACK_DEPTH];
+ int numCallers_;
+ int skip_;
+};
+
+// Define the constructors non-inline, so they consistently add a single
+// frame to the stack trace, regardless of whether optimization is enabled
+Backtrace::Backtrace(int skip)
+ : skip_(skip + 1) // ignore the constructor itself
+{
+ numCallers_ = backtrace(callers_, MAX_STACK_DEPTH);
+ if (skip_ > numCallers_) {
+ skip_ = numCallers_;
+ }
+}
+
+Backtrace::Backtrace(Backtrace const &bt)
+ : numCallers_(bt.numCallers_)
+ , skip_(bt.skip_) {
+ if (numCallers_ >= 0) {
+ memcpy(callers_, bt.callers_, numCallers_ * sizeof(void*));
+ }
+}
+
+/**
+ * A backtrace, plus one or two type names
+ */
+class Key {
+ public:
+ class Hash {
+ public:
+ size_t operator()(Key const& k) const {
+ return k.hash();
+ }
+ };
+
+ Key(const Backtrace* bt, const std::type_info& type_info)
+ : backtrace_(bt)
+ , typeName1_(type_info.name())
+ , typeName2_(NULL) {
+ }
+
+ Key(const Backtrace* bt, const std::type_info& type_info1,
+ const std::type_info& type_info2)
+ : backtrace_(bt)
+ , typeName1_(type_info1.name())
+ , typeName2_(type_info2.name()) {
+ }
+
+ Key(const Key& k)
+ : backtrace_(k.backtrace_)
+ , typeName1_(k.typeName1_)
+ , typeName2_(k.typeName2_) {
+ }
+
+ void operator=(const Key& k) {
+ backtrace_ = k.backtrace_;
+ typeName1_ = k.typeName1_;
+ typeName2_ = k.typeName2_;
+ }
+
+ const Backtrace* getBacktrace() const {
+ return backtrace_;
+ }
+
+ const char* getTypeName() const {
+ return typeName1_;
+ }
+
+ const char* getTypeName2() const {
+ return typeName2_;
+ }
+
+ void makePersistent() {
+ // Copy the Backtrace object
+ backtrace_ = new Backtrace(*backtrace_);
+
+ // NOTE: We don't copy the type name.
+ // The GNU libstdc++ implementation of type_info::name() returns a value
+ // that will be valid for the lifetime of the program. (Although the C++
+ // standard doesn't guarantee this will be true on all implementations.)
+ }
+
+ /**
+ * Clean up memory allocated by makePersistent()
+ *
+ * Should only be invoked if makePersistent() has previously been called.
+ * The Key should no longer be used after cleanup() is called.
+ */
+ void cleanup() {
+ delete backtrace_;
+ backtrace_ = NULL;
+ }
+
+ int cmp(const Key& k) const {
+ int ret = backtrace_->cmp(*k.backtrace_);
+ if (ret != 0) {
+ return ret;
+ }
+
+ // NOTE: We compare just the name pointers.
+ // With GNU libstdc++, every type_info object for the same type points to
+ // exactly the same name string. (Although this isn't guaranteed by the
+ // C++ standard.)
+ ret = k.typeName1_ - typeName1_;
+ if (ret != 0) {
+ return ret;
+ }
+ return k.typeName2_ - typeName2_;
+ }
+
+ bool operator==(const Key& k) const {
+ return cmp(k) == 0;
+ }
+
+ size_t hash() const {
+ // NOTE: As above, we just use the name pointer value.
+ // Works with GNU libstdc++, but not guaranteed to be correct on all
+ // implementations.
+ return backtrace_->hash() ^
+ reinterpret_cast<size_t>(typeName1_) ^
+ reinterpret_cast<size_t>(typeName2_);
+ }
+
+ private:
+ const Backtrace* backtrace_;
+ const char* typeName1_;
+ const char* typeName2_;
+};
+
+/**
+ * A functor that determines which of two BacktraceMap entries
+ * has a higher count.
+ */
+class CountGreater {
+ public:
+ bool operator()(std::pair<Key, size_t> bt1,
+ std::pair<Key, size_t> bt2) const {
+ return bt1.second > bt2.second;
+ }
+};
+
+typedef __gnu_cxx::hash_map<Key, size_t, Key::Hash> BacktraceMap;
+
+/**
+ * A map describing how many times T_VIRTUAL_CALL() has been invoked.
+ */
+BacktraceMap virtual_calls;
+Mutex virtual_calls_mutex;
+
+/**
+ * A map describing how many times T_GENERIC_PROTOCOL() has been invoked.
+ */
+BacktraceMap generic_calls;
+Mutex generic_calls_mutex;
+
+
+void _record_backtrace(BacktraceMap* map, const Mutex& mutex, Key *k) {
+ Guard guard(mutex);
+
+ BacktraceMap::iterator it = map->find(*k);
+ if (it == map->end()) {
+ k->makePersistent();
+ map->insert(std::make_pair(*k, 1));
+ } else {
+ // increment the count
+ // NOTE: we could assert if it->second is 0 afterwards, since that would
+ // mean we've wrapped.
+ ++(it->second);
+ }
+}
+
+/**
+ * Record an unnecessary virtual function call.
+ *
+ * This method is invoked by the T_VIRTUAL_CALL() macro.
+ */
+void profile_virtual_call(const std::type_info& type) {
+ int const skip = 1; // ignore this frame
+ Backtrace bt(skip);
+ Key k(&bt, type);
+ _record_backtrace(&virtual_calls, virtual_calls_mutex, &k);
+}
+
+/**
+ * Record a call to a template processor with a protocol that is not the one
+ * specified in the template parameter.
+ *
+ * This method is invoked by the T_GENERIC_PROTOCOL() macro.
+ */
+void profile_generic_protocol(const std::type_info& template_type,
+ const std::type_info& prot_type) {
+ int const skip = 1; // ignore this frame
+ Backtrace bt(skip);
+ Key k(&bt, template_type, prot_type);
+ _record_backtrace(&generic_calls, generic_calls_mutex, &k);
+}
+
+/**
+ * Print the recorded profiling information to the specified file.
+ */
+void profile_print_info(FILE* f) {
+ typedef std::vector< std::pair<Key, size_t> > BacktraceVector;
+
+ CountGreater is_greater;
+
+ // Grab both locks for the duration of the print operation,
+ // to ensure the output is a consistent snapshot of a single point in time
+ Guard generic_calls_guard(generic_calls_mutex);
+ Guard virtual_calls_guard(virtual_calls_mutex);
+
+ // print the info from generic_calls, sorted by frequency
+ //
+ // We print the generic_calls info ahead of virtual_calls, since it is more
+ // useful in some cases. All T_GENERIC_PROTOCOL calls can be eliminated
+ // from most programs. Not all T_VIRTUAL_CALLs will be eliminated by
+ // converting to templates.
+ BacktraceVector gp_sorted(generic_calls.begin(), generic_calls.end());
+ std::sort(gp_sorted.begin(), gp_sorted.end(), is_greater);
+
+ for (BacktraceVector::const_iterator it = gp_sorted.begin();
+ it != gp_sorted.end();
+ ++it) {
+ Key const &key = it->first;
+ size_t const count = it->second;
+ fprintf(f, "T_GENERIC_PROTOCOL: %zu calls to %s with a %s:\n",
+ count, key.getTypeName(), key.getTypeName2());
+ key.getBacktrace()->print(f, 2);
+ fprintf(f, "\n");
+ }
+
+ // print the info from virtual_calls, sorted by frequency
+ BacktraceVector vc_sorted(virtual_calls.begin(), virtual_calls.end());
+ std::sort(vc_sorted.begin(), vc_sorted.end(), is_greater);
+
+ for (BacktraceVector::const_iterator it = vc_sorted.begin();
+ it != vc_sorted.end();
+ ++it) {
+ Key const &key = it->first;
+ size_t const count = it->second;
+ fprintf(f, "T_VIRTUAL_CALL: %zu calls on %s:\n", count, key.getTypeName());
+ key.getBacktrace()->print(f, 2);
+ fprintf(f, "\n");
+ }
+}
+
+/**
+ * Print the recorded profiling information to stdout.
+ */
+void profile_print_info() {
+ profile_print_info(stdout);
+}
+
+/**
+ * Write a BacktraceMap as Google CPU profiler binary data.
+ */
+static void profile_write_pprof_file(FILE* f, BacktraceMap const& map) {
+ // Write the header
+ uintptr_t header[5] = { 0, 3, 0, 0, 0 };
+ fwrite(&header, sizeof(header), 1, f);
+
+ // Write the profile records
+ for (BacktraceMap::const_iterator it = map.begin(); it != map.end(); ++it) {
+ uintptr_t count = it->second;
+ fwrite(&count, sizeof(count), 1, f);
+
+ Backtrace const* bt = it->first.getBacktrace();
+ uintptr_t num_pcs = bt->getDepth();
+ fwrite(&num_pcs, sizeof(num_pcs), 1, f);
+
+ for (uintptr_t n = 0; n < num_pcs; ++n) {
+ void* pc = bt->getFrame(n);
+ fwrite(&pc, sizeof(pc), 1, f);
+ }
+ }
+
+ // Write the trailer
+ uintptr_t trailer[3] = { 0, 1, 0 };
+ fwrite(&trailer, sizeof(trailer), 1, f);
+
+ // Write /proc/self/maps
+ // TODO(simpkins): This only works on linux
+ FILE *proc_maps = fopen("/proc/self/maps", "r");
+ if (proc_maps) {
+ uint8_t buf[4096];
+ while (true) {
+ size_t bytes_read = fread(buf, 1, sizeof(buf), proc_maps);
+ if (bytes_read == 0) {
+ break;
+ }
+ fwrite(buf, 1, bytes_read, f);
+ }
+ fclose(proc_maps);
+ }
+}
+
+/**
+ * Write the recorded profiling information as pprof files.
+ *
+ * This writes the information using the Google CPU profiler binary data
+ * format, so it can be analyzed with pprof. Note that information about the
+ * protocol/transport data types cannot be stored in this file format.
+ *
+ * See http://code.google.com/p/google-perftools/ for more details.
+ *
+ * @param gen_calls_f The information about calls to
+ * profile_generic_protocol() will be written to this
+ * file.
+ * @param virtual_calls_f The information about calls to
+ * profile_virtual_call() will be written to this file.
+ */
+void profile_write_pprof(FILE* gen_calls_f, FILE* virtual_calls_f) {
+ typedef std::vector< std::pair<Key, size_t> > BacktraceVector;
+
+ CountGreater is_greater;
+
+ // Grab both locks for the duration of the print operation,
+ // to ensure the output is a consistent snapshot of a single point in time
+ Guard generic_calls_guard(generic_calls_mutex);
+ Guard virtual_calls_guard(virtual_calls_mutex);
+
+ // write the info from generic_calls
+ profile_write_pprof_file(gen_calls_f, generic_calls);
+
+ // write the info from virtual_calls
+ profile_write_pprof_file(virtual_calls_f, virtual_calls);
+}
+
+}} // apache::thrift
+
+#endif // T_GLOBAL_PROFILE_VIRTUAL > 0
http://git-wip-us.apache.org/repos/asf/airavata/blob/f891b7dc/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncBufferProcessor.h
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncBufferProcessor.h b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncBufferProcessor.h
new file mode 100644
index 0000000..ad7c639
--- /dev/null
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncBufferProcessor.h
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _THRIFT_TASYNC_BUFFER_PROCESSOR_H_
+#define _THRIFT_TASYNC_BUFFER_PROCESSOR_H_ 1
+
+#include <thrift/cxxfunctional.h>
+#include <boost/shared_ptr.hpp>
+
+#include <thrift/transport/TBufferTransports.h>
+
+namespace apache { namespace thrift { namespace async {
+
+class TAsyncBufferProcessor {
+ public:
+ // Process data in "in", putting the result in "out".
+ // Call _return(true) when done, or _return(false) to
+ // forcefully close the connection (if applicable).
+ // "in" and "out" should be TMemoryBuffer or similar,
+ // not a wrapper around a socket.
+ virtual void process(
+ apache::thrift::stdcxx::function<void(bool healthy)> _return,
+ boost::shared_ptr<apache::thrift::transport::TBufferBase> ibuf,
+ boost::shared_ptr<apache::thrift::transport::TBufferBase> obuf) = 0;
+ virtual ~TAsyncBufferProcessor() {}
+};
+
+}}} // apache::thrift::async
+
+#endif // #ifndef _THRIFT_TASYNC_BUFFER_PROCESSOR_H_
http://git-wip-us.apache.org/repos/asf/airavata/blob/f891b7dc/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncChannel.cpp
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncChannel.cpp b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncChannel.cpp
new file mode 100644
index 0000000..64dfe5f
--- /dev/null
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncChannel.cpp
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <thrift/async/TAsyncChannel.h>
+#include <thrift/cxxfunctional.h>
+
+namespace apache { namespace thrift { namespace async {
+
+void TAsyncChannel::sendAndRecvMessage(const VoidCallback& cob,
+ TMemoryBuffer* sendBuf,
+ TMemoryBuffer* recvBuf) {
+ apache::thrift::stdcxx::function<void()> send_done =
+ apache::thrift::stdcxx::bind(&TAsyncChannel::recvMessage, this, cob, recvBuf);
+
+ sendMessage(send_done, sendBuf);
+}
+
+}}} // apache::thrift::async
http://git-wip-us.apache.org/repos/asf/airavata/blob/f891b7dc/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncChannel.h
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncChannel.h b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncChannel.h
new file mode 100644
index 0000000..0f202fd
--- /dev/null
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncChannel.h
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _THRIFT_ASYNC_TASYNCCHANNEL_H_
+#define _THRIFT_ASYNC_TASYNCCHANNEL_H_ 1
+
+#include <thrift/cxxfunctional.h>
+#include <thrift/Thrift.h>
+
+namespace apache { namespace thrift { namespace transport {
+class TMemoryBuffer;
+}}}
+
+namespace apache { namespace thrift { namespace async {
+using apache::thrift::transport::TMemoryBuffer;
+
+class TAsyncChannel {
+ public:
+ typedef apache::thrift::stdcxx::function<void()> VoidCallback;
+
+ virtual ~TAsyncChannel() {}
+
+ // is the channel in a good state?
+ virtual bool good() const = 0;
+ virtual bool error() const = 0;
+ virtual bool timedOut() const = 0;
+
+ /**
+ * Send a message over the channel.
+ */
+ virtual void sendMessage(const VoidCallback& cob,
+ apache::thrift::transport::TMemoryBuffer* message) = 0;
+
+ /**
+ * Receive a message from the channel.
+ */
+ virtual void recvMessage(const VoidCallback& cob,
+ apache::thrift::transport::TMemoryBuffer* message) = 0;
+
+ /**
+ * Send a message over the channel and receive a response.
+ */
+ virtual void sendAndRecvMessage(const VoidCallback& cob,
+ apache::thrift::transport::TMemoryBuffer* sendBuf,
+ apache::thrift::transport::TMemoryBuffer* recvBuf);
+};
+
+}}} // apache::thrift::async
+
+#endif // #ifndef _THRIFT_ASYNC_TASYNCCHANNEL_H_
http://git-wip-us.apache.org/repos/asf/airavata/blob/f891b7dc/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncDispatchProcessor.h
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncDispatchProcessor.h b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncDispatchProcessor.h
new file mode 100644
index 0000000..15b5bce
--- /dev/null
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncDispatchProcessor.h
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef _THRIFT_ASYNC_TASYNCDISPATCHPROCESSOR_H_
+#define _THRIFT_ASYNC_TASYNCDISPATCHPROCESSOR_H_ 1
+
+#include <thrift/async/TAsyncProcessor.h>
+
+namespace apache { namespace thrift { namespace async {
+
+/**
+ * TAsyncDispatchProcessor is a helper class to parse the message header then
+ * call another function to dispatch based on the function name.
+ *
+ * Subclasses must implement dispatchCall() to dispatch on the function name.
+ */
+template <class Protocol_>
+class TAsyncDispatchProcessorT : public TAsyncProcessor {
+ public:
+ virtual void process(apache::thrift::stdcxx::function<void(bool success)> _return,
+ boost::shared_ptr<protocol::TProtocol> in,
+ boost::shared_ptr<protocol::TProtocol> out) {
+ protocol::TProtocol* inRaw = in.get();
+ protocol::TProtocol* outRaw = out.get();
+
+ // Try to dynamic cast to the template protocol type
+ Protocol_* specificIn = dynamic_cast<Protocol_*>(inRaw);
+ Protocol_* specificOut = dynamic_cast<Protocol_*>(outRaw);
+ if (specificIn && specificOut) {
+ return processFast(_return, specificIn, specificOut);
+ }
+
+ // Log the fact that we have to use the slow path
+ T_GENERIC_PROTOCOL(this, inRaw, specificIn);
+ T_GENERIC_PROTOCOL(this, outRaw, specificOut);
+
+ std::string fname;
+ protocol::TMessageType mtype;
+ int32_t seqid;
+ inRaw->readMessageBegin(fname, mtype, seqid);
+
+ // If this doesn't look like a valid call, log an error and return false so
+ // that the server will close the connection.
+ //
+ // (The old generated processor code used to try to skip a T_STRUCT and
+ // continue. However, that seems unsafe.)
+ if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) {
+ GlobalOutput.printf("received invalid message type %d from client",
+ mtype);
+ _return(false);
+ return;
+ }
+
+ return this->dispatchCall(_return, inRaw, outRaw, fname, seqid);
+ }
+
+ void processFast(apache::thrift::stdcxx::function<void(bool success)> _return,
+ Protocol_* in, Protocol_* out) {
+ std::string fname;
+ protocol::TMessageType mtype;
+ int32_t seqid;
+ in->readMessageBegin(fname, mtype, seqid);
+
+ if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) {
+ GlobalOutput.printf("received invalid message type %d from client",
+ mtype);
+ _return(false);
+ return;
+ }
+
+ return this->dispatchCallTemplated(_return, in, out, fname, seqid);
+ }
+
+ virtual void dispatchCall(apache::thrift::stdcxx::function<void(bool ok)> _return,
+ apache::thrift::protocol::TProtocol* in,
+ apache::thrift::protocol::TProtocol* out,
+ const std::string& fname, int32_t seqid) = 0;
+
+ virtual void dispatchCallTemplated(apache::thrift::stdcxx::function<void(bool ok)> _return,
+ Protocol_* in, Protocol_* out,
+ const std::string& fname,
+ int32_t seqid) = 0;
+};
+
+/**
+ * Non-templatized version of TAsyncDispatchProcessor,
+ * that doesn't bother trying to perform a dynamic_cast.
+ */
+class TAsyncDispatchProcessor : public TAsyncProcessor {
+ public:
+ virtual void process(apache::thrift::stdcxx::function<void(bool success)> _return,
+ boost::shared_ptr<protocol::TProtocol> in,
+ boost::shared_ptr<protocol::TProtocol> out) {
+ protocol::TProtocol* inRaw = in.get();
+ protocol::TProtocol* outRaw = out.get();
+
+ std::string fname;
+ protocol::TMessageType mtype;
+ int32_t seqid;
+ inRaw->readMessageBegin(fname, mtype, seqid);
+
+ // If this doesn't look like a valid call, log an error and return false so
+ // that the server will close the connection.
+ //
+ // (The old generated processor code used to try to skip a T_STRUCT and
+ // continue. However, that seems unsafe.)
+ if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) {
+ GlobalOutput.printf("received invalid message type %d from client",
+ mtype);
+ _return(false);
+ return;
+ }
+
+ return dispatchCall(_return, inRaw, outRaw, fname, seqid);
+ }
+
+ virtual void dispatchCall(apache::thrift::stdcxx::function<void(bool ok)> _return,
+ apache::thrift::protocol::TProtocol* in,
+ apache::thrift::protocol::TProtocol* out,
+ const std::string& fname, int32_t seqid) = 0;
+};
+
+// Specialize TAsyncDispatchProcessorT for TProtocol and TDummyProtocol just to
+// use the generic TDispatchProcessor.
+template <>
+class TAsyncDispatchProcessorT<protocol::TDummyProtocol> :
+ public TAsyncDispatchProcessor {};
+template <>
+class TAsyncDispatchProcessorT<protocol::TProtocol> :
+ public TAsyncDispatchProcessor {};
+
+}}} // apache::thrift::async
+
+#endif // _THRIFT_ASYNC_TASYNCDISPATCHPROCESSOR_H_
http://git-wip-us.apache.org/repos/asf/airavata/blob/f891b7dc/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncProcessor.h
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncProcessor.h b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncProcessor.h
new file mode 100644
index 0000000..a03d1dc
--- /dev/null
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncProcessor.h
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _THRIFT_TASYNCPROCESSOR_H_
+#define _THRIFT_TASYNCPROCESSOR_H_ 1
+
+#include <thrift/cxxfunctional.h>
+#include <boost/shared_ptr.hpp>
+#include <thrift/protocol/TProtocol.h>
+#include <thrift/TProcessor.h>
+
+namespace apache { namespace thrift { namespace async {
+
+/**
+ * Async version of a TProcessor. It is not expected to complete by the time
+ * the call to process returns. Instead, it calls a cob to signal completion.
+ */
+
+class TEventServer; // forward declaration
+
+class TAsyncProcessor {
+ public:
+ virtual ~TAsyncProcessor() {}
+
+ virtual void process(apache::thrift::stdcxx::function<void(bool success)> _return,
+ boost::shared_ptr<protocol::TProtocol> in,
+ boost::shared_ptr<protocol::TProtocol> out) = 0;
+
+ void process(apache::thrift::stdcxx::function<void(bool success)> _return,
+ boost::shared_ptr<apache::thrift::protocol::TProtocol> io) {
+ return process(_return, io, io);
+ }
+
+ boost::shared_ptr<TProcessorEventHandler> getEventHandler() {
+ return eventHandler_;
+ }
+
+ void setEventHandler(boost::shared_ptr<TProcessorEventHandler> eventHandler) {
+ eventHandler_ = eventHandler;
+ }
+
+ const TEventServer* getAsyncServer() {
+ return asyncServer_;
+ }
+ protected:
+ TAsyncProcessor() {}
+
+ boost::shared_ptr<TProcessorEventHandler> eventHandler_;
+ const TEventServer* asyncServer_;
+ private:
+ friend class TEventServer;
+ void setAsyncServer(const TEventServer* server) {
+ asyncServer_ = server;
+ }
+};
+
+class TAsyncProcessorFactory {
+ public:
+ virtual ~TAsyncProcessorFactory() {}
+
+ /**
+ * Get the TAsyncProcessor to use for a particular connection.
+ *
+ * This method is always invoked in the same thread that the connection was
+ * accepted on. This generally means that this call does not need to be
+ * thread safe, as it will always be invoked from a single thread.
+ */
+ virtual boost::shared_ptr<TAsyncProcessor> getProcessor(
+ const TConnectionInfo& connInfo) = 0;
+};
+
+
+
+}}} // apache::thrift::async
+
+// XXX I'm lazy for now
+namespace apache { namespace thrift {
+using apache::thrift::async::TAsyncProcessor;
+}}
+
+#endif // #ifndef _THRIFT_TASYNCPROCESSOR_H_
http://git-wip-us.apache.org/repos/asf/airavata/blob/f891b7dc/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncProtocolProcessor.cpp
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncProtocolProcessor.cpp b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncProtocolProcessor.cpp
new file mode 100644
index 0000000..2096289
--- /dev/null
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncProtocolProcessor.cpp
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <thrift/async/TAsyncProtocolProcessor.h>
+
+using apache::thrift::transport::TBufferBase;
+using apache::thrift::protocol::TProtocol;
+
+namespace apache { namespace thrift { namespace async {
+
+void TAsyncProtocolProcessor::process(
+ apache::thrift::stdcxx::function<void(bool healthy)> _return,
+ boost::shared_ptr<TBufferBase> ibuf,
+ boost::shared_ptr<TBufferBase> obuf) {
+ boost::shared_ptr<TProtocol> iprot(pfact_->getProtocol(ibuf));
+ boost::shared_ptr<TProtocol> oprot(pfact_->getProtocol(obuf));
+ return underlying_->process(
+ apache::thrift::stdcxx::bind(
+ &TAsyncProtocolProcessor::finish,
+ _return,
+ oprot,
+ apache::thrift::stdcxx::placeholders::_1),
+ iprot, oprot);
+}
+
+/* static */ void TAsyncProtocolProcessor::finish(
+ apache::thrift::stdcxx::function<void(bool healthy)> _return,
+ boost::shared_ptr<TProtocol> oprot,
+ bool healthy) {
+ (void) oprot;
+ // This is a stub function to hold a reference to oprot.
+ return _return(healthy);
+}
+
+}}} // apache::thrift::async
http://git-wip-us.apache.org/repos/asf/airavata/blob/f891b7dc/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncProtocolProcessor.h
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncProtocolProcessor.h b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncProtocolProcessor.h
new file mode 100644
index 0000000..840b4dd
--- /dev/null
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TAsyncProtocolProcessor.h
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _THRIFT_TNAME_ME_H_
+#define _THRIFT_TNAME_ME_H_ 1
+
+#include <thrift/async/TAsyncProcessor.h>
+#include <thrift/async/TAsyncBufferProcessor.h>
+#include <thrift/protocol/TProtocol.h>
+
+namespace apache { namespace thrift { namespace async {
+
+class TAsyncProtocolProcessor : public TAsyncBufferProcessor {
+ public:
+ TAsyncProtocolProcessor(
+ boost::shared_ptr<TAsyncProcessor> underlying,
+ boost::shared_ptr<apache::thrift::protocol::TProtocolFactory> pfact)
+ : underlying_(underlying)
+ , pfact_(pfact)
+ {}
+
+ virtual void process(
+ apache::thrift::stdcxx::function<void(bool healthy)> _return,
+ boost::shared_ptr<apache::thrift::transport::TBufferBase> ibuf,
+ boost::shared_ptr<apache::thrift::transport::TBufferBase> obuf);
+
+ virtual ~TAsyncProtocolProcessor() {}
+
+ private:
+ static void finish(
+ apache::thrift::stdcxx::function<void(bool healthy)> _return,
+ boost::shared_ptr<apache::thrift::protocol::TProtocol> oprot,
+ bool healthy);
+
+ boost::shared_ptr<TAsyncProcessor> underlying_;
+ boost::shared_ptr<apache::thrift::protocol::TProtocolFactory> pfact_;
+};
+
+}}} // apache::thrift::async
+
+#endif // #ifndef _THRIFT_TNAME_ME_H_
http://git-wip-us.apache.org/repos/asf/airavata/blob/f891b7dc/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TEvhttpClientChannel.cpp
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TEvhttpClientChannel.cpp b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TEvhttpClientChannel.cpp
new file mode 100644
index 0000000..7ad7537
--- /dev/null
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TEvhttpClientChannel.cpp
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <thrift/async/TEvhttpClientChannel.h>
+#include <evhttp.h>
+#include <thrift/transport/TBufferTransports.h>
+#include <thrift/protocol/TProtocolException.h>
+
+#include <iostream>
+#include <sstream>
+
+using namespace apache::thrift::protocol;
+using apache::thrift::transport::TTransportException;
+
+namespace apache { namespace thrift { namespace async {
+
+
+TEvhttpClientChannel::TEvhttpClientChannel(
+ const std::string& host,
+ const std::string& path,
+ const char* address,
+ int port,
+ struct event_base* eb)
+ : host_(host)
+ , path_(path)
+ , recvBuf_(NULL)
+ , conn_(NULL)
+{
+ conn_ = evhttp_connection_new(address, port);
+ if (conn_ == NULL) {
+ throw TException("evhttp_connection_new failed");
+ }
+ evhttp_connection_set_base(conn_, eb);
+}
+
+
+TEvhttpClientChannel::~TEvhttpClientChannel() {
+ if (conn_ != NULL) {
+ evhttp_connection_free(conn_);
+ }
+}
+
+
+void TEvhttpClientChannel::sendAndRecvMessage(
+ const VoidCallback& cob,
+ apache::thrift::transport::TMemoryBuffer* sendBuf,
+ apache::thrift::transport::TMemoryBuffer* recvBuf) {
+ cob_ = cob;
+ recvBuf_ = recvBuf;
+
+ struct evhttp_request* req = evhttp_request_new(response, this);
+ if (req == NULL) {
+ throw TException("evhttp_request_new failed");
+ }
+
+ int rv;
+
+ rv = evhttp_add_header(req->output_headers, "Host", host_.c_str());
+ if (rv != 0) {
+ throw TException("evhttp_add_header failed");
+ }
+
+ rv = evhttp_add_header(req->output_headers, "Content-Type", "application/x-thrift");
+ if (rv != 0) {
+ throw TException("evhttp_add_header failed");
+ }
+
+ uint8_t* obuf;
+ uint32_t sz;
+ sendBuf->getBuffer(&obuf, &sz);
+ rv = evbuffer_add(req->output_buffer, obuf, sz);
+ if (rv != 0) {
+ throw TException("evbuffer_add failed");
+ }
+
+ rv = evhttp_make_request(conn_, req, EVHTTP_REQ_POST, path_.c_str());
+ if (rv != 0) {
+ throw TException("evhttp_make_request failed");
+ }
+}
+
+
+void TEvhttpClientChannel::sendMessage(
+ const VoidCallback& cob, apache::thrift::transport::TMemoryBuffer* message) {
+ (void) cob;
+ (void) message;
+ throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
+ "Unexpected call to TEvhttpClientChannel::sendMessage");
+}
+
+
+void TEvhttpClientChannel::recvMessage(
+ const VoidCallback& cob, apache::thrift::transport::TMemoryBuffer* message) {
+ (void) cob;
+ (void) message;
+ throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
+ "Unexpected call to TEvhttpClientChannel::recvMessage");
+}
+
+
+void TEvhttpClientChannel::finish(struct evhttp_request* req) {
+ if (req == NULL) {
+ try {
+ cob_();
+ } catch(const TTransportException& e) {
+ if(e.getType() == TTransportException::END_OF_FILE)
+ throw TException("connect failed");
+ else
+ throw;
+ }
+ return;
+ } else if (req->response_code != 200) {
+ try {
+ cob_();
+ } catch(const TTransportException& e) {
+ std::stringstream ss;
+ ss << "server returned code " << req->response_code;
+ if(req->response_code_line)
+ ss << ": " << req->response_code_line;
+ if(e.getType() == TTransportException::END_OF_FILE)
+ throw TException(ss.str());
+ else
+ throw;
+ }
+ return;
+ }
+ recvBuf_->resetBuffer(
+ EVBUFFER_DATA(req->input_buffer),
+ static_cast<uint32_t>(EVBUFFER_LENGTH(req->input_buffer)));
+ cob_();
+ return;
+}
+
+
+/* static */ void TEvhttpClientChannel::response(struct evhttp_request* req, void* arg) {
+ TEvhttpClientChannel* self = (TEvhttpClientChannel*)arg;
+ try {
+ self->finish(req);
+ } catch(std::exception& e) {
+ // don't propagate a C++ exception in C code (e.g. libevent)
+ std::cerr << "TEvhttpClientChannel::response exception thrown (ignored): " << e.what() << std::endl;
+ }
+}
+
+
+}}} // apache::thrift::async
http://git-wip-us.apache.org/repos/asf/airavata/blob/f891b7dc/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TEvhttpClientChannel.h
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TEvhttpClientChannel.h b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TEvhttpClientChannel.h
new file mode 100644
index 0000000..a7229e9
--- /dev/null
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TEvhttpClientChannel.h
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _THRIFT_TEVHTTP_CLIENT_CHANNEL_H_
+#define _THRIFT_TEVHTTP_CLIENT_CHANNEL_H_ 1
+
+#include <string>
+#include <boost/shared_ptr.hpp>
+#include <thrift/async/TAsyncChannel.h>
+
+struct event_base;
+struct evhttp_connection;
+struct evhttp_request;
+
+namespace apache { namespace thrift { namespace transport {
+class TMemoryBuffer;
+}}}
+
+namespace apache { namespace thrift { namespace async {
+
+class TEvhttpClientChannel : public TAsyncChannel {
+ public:
+ using TAsyncChannel::VoidCallback;
+
+ TEvhttpClientChannel(
+ const std::string& host,
+ const std::string& path,
+ const char* address,
+ int port,
+ struct event_base* eb);
+ ~TEvhttpClientChannel();
+
+ virtual void sendAndRecvMessage(const VoidCallback& cob,
+ apache::thrift::transport::TMemoryBuffer* sendBuf,
+ apache::thrift::transport::TMemoryBuffer* recvBuf);
+
+ virtual void sendMessage(const VoidCallback& cob, apache::thrift::transport::TMemoryBuffer* message);
+ virtual void recvMessage(const VoidCallback& cob, apache::thrift::transport::TMemoryBuffer* message);
+
+ void finish(struct evhttp_request* req);
+
+ //XXX
+ virtual bool good() const { return true; }
+ virtual bool error() const { return false; }
+ virtual bool timedOut() const { return false; }
+
+ private:
+ static void response(struct evhttp_request* req, void* arg);
+
+ std::string host_;
+ std::string path_;
+ VoidCallback cob_;
+ apache::thrift::transport::TMemoryBuffer* recvBuf_;
+ struct evhttp_connection* conn_;
+
+};
+
+}}} // apache::thrift::async
+
+#endif // #ifndef _THRIFT_TEVHTTP_CLIENT_CHANNEL_H_
http://git-wip-us.apache.org/repos/asf/airavata/blob/f891b7dc/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TEvhttpServer.cpp
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TEvhttpServer.cpp b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TEvhttpServer.cpp
new file mode 100644
index 0000000..fa8d782
--- /dev/null
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TEvhttpServer.cpp
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <thrift/async/TEvhttpServer.h>
+#include <thrift/async/TAsyncBufferProcessor.h>
+#include <thrift/transport/TBufferTransports.h>
+#include <evhttp.h>
+
+#include <iostream>
+
+#ifndef HTTP_INTERNAL // libevent < 2
+#define HTTP_INTERNAL 500
+#endif
+
+using apache::thrift::transport::TMemoryBuffer;
+
+namespace apache { namespace thrift { namespace async {
+
+
+struct TEvhttpServer::RequestContext {
+ struct evhttp_request* req;
+ boost::shared_ptr<apache::thrift::transport::TMemoryBuffer> ibuf;
+ boost::shared_ptr<apache::thrift::transport::TMemoryBuffer> obuf;
+
+ RequestContext(struct evhttp_request* req);
+};
+
+
+TEvhttpServer::TEvhttpServer(boost::shared_ptr<TAsyncBufferProcessor> processor)
+ : processor_(processor)
+ , eb_(NULL)
+ , eh_(NULL)
+{}
+
+
+TEvhttpServer::TEvhttpServer(boost::shared_ptr<TAsyncBufferProcessor> processor, int port)
+ : processor_(processor)
+ , eb_(NULL)
+ , eh_(NULL)
+{
+ // Create event_base and evhttp.
+ eb_ = event_base_new();
+ if (eb_ == NULL) {
+ throw TException("event_base_new failed");
+ }
+ eh_ = evhttp_new(eb_);
+ if (eh_ == NULL) {
+ event_base_free(eb_);
+ throw TException("evhttp_new failed");
+ }
+
+ // Bind to port.
+ int ret = evhttp_bind_socket(eh_, NULL, port);
+ if (ret < 0) {
+ evhttp_free(eh_);
+ event_base_free(eb_);
+ throw TException("evhttp_bind_socket failed");
+ }
+
+ // Register a handler. If you use the other constructor,
+ // you will want to do this yourself.
+ // Don't forget to unregister before destorying this TEvhttpServer.
+ evhttp_set_cb(eh_, "/", request, (void*)this);
+}
+
+
+TEvhttpServer::~TEvhttpServer() {
+ if (eh_ != NULL) {
+ evhttp_free(eh_);
+ }
+ if (eb_ != NULL) {
+ event_base_free(eb_);
+ }
+}
+
+
+int TEvhttpServer::serve() {
+ if (eb_ == NULL) {
+ throw TException("Unexpected call to TEvhttpServer::serve");
+ }
+ return event_base_dispatch(eb_);
+}
+
+
+TEvhttpServer::RequestContext::RequestContext(struct evhttp_request* req) : req(req)
+ , ibuf(new TMemoryBuffer(EVBUFFER_DATA(req->input_buffer), static_cast<uint32_t>(EVBUFFER_LENGTH(req->input_buffer))))
+ , obuf(new TMemoryBuffer())
+{}
+
+
+void TEvhttpServer::request(struct evhttp_request* req, void* self) {
+ try {
+ static_cast<TEvhttpServer*>(self)->process(req);
+ } catch(std::exception& e) {
+ evhttp_send_reply(req, HTTP_INTERNAL, e.what(), 0);
+ }
+}
+
+
+void TEvhttpServer::process(struct evhttp_request* req) {
+ RequestContext* ctx = new RequestContext(req);
+ return processor_->process(
+ apache::thrift::stdcxx::bind(
+ &TEvhttpServer::complete,
+ this,
+ ctx,
+ apache::thrift::stdcxx::placeholders::_1),
+ ctx->ibuf,
+ ctx->obuf);
+}
+
+
+void TEvhttpServer::complete(RequestContext* ctx, bool success) {
+ (void) success;
+ std::auto_ptr<RequestContext> ptr(ctx);
+
+ int code = success ? 200 : 400;
+ const char* reason = success ? "OK" : "Bad Request";
+
+ int rv = evhttp_add_header(ctx->req->output_headers, "Content-Type", "application/x-thrift");
+ if (rv != 0) {
+ // TODO: Log an error.
+ std::cerr << "evhttp_add_header failed " << __FILE__ << ":" << __LINE__ << std::endl;
+ }
+
+ struct evbuffer* buf = evbuffer_new();
+ if (buf == NULL) {
+ // TODO: Log an error.
+ std::cerr << "evbuffer_new failed " << __FILE__ << ":" << __LINE__ << std::endl;
+ } else {
+ uint8_t* obuf;
+ uint32_t sz;
+ ctx->obuf->getBuffer(&obuf, &sz);
+ int ret = evbuffer_add(buf, obuf, sz);
+ if (ret != 0) {
+ // TODO: Log an error.
+ std::cerr << "evhttp_add failed with " << ret << " " << __FILE__ << ":" << __LINE__ << std::endl;
+ }
+ }
+
+ evhttp_send_reply(ctx->req, code, reason, buf);
+ if (buf != NULL) {
+ evbuffer_free(buf);
+ }
+}
+
+
+struct event_base* TEvhttpServer::getEventBase() {
+ return eb_;
+}
+
+
+}}} // apache::thrift::async
http://git-wip-us.apache.org/repos/asf/airavata/blob/f891b7dc/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TEvhttpServer.h
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TEvhttpServer.h b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TEvhttpServer.h
new file mode 100644
index 0000000..edc6ffb
--- /dev/null
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/async/TEvhttpServer.h
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _THRIFT_TEVHTTP_SERVER_H_
+#define _THRIFT_TEVHTTP_SERVER_H_ 1
+
+#include <boost/shared_ptr.hpp>
+
+struct event_base;
+struct evhttp;
+struct evhttp_request;
+
+namespace apache { namespace thrift { namespace async {
+
+class TAsyncBufferProcessor;
+
+class TEvhttpServer {
+ public:
+ /**
+ * Create a TEvhttpServer for use with an external evhttp instance.
+ * Must be manually installed with evhttp_set_cb, using
+ * TEvhttpServer::request as the callback and the
+ * address of the server as the extra arg.
+ * Do not call "serve" on this server.
+ */
+ TEvhttpServer(boost::shared_ptr<TAsyncBufferProcessor> processor);
+
+ /**
+ * Create a TEvhttpServer with an embedded event_base and evhttp,
+ * listening on port and responding on the endpoint "/".
+ * Call "serve" on this server to serve forever.
+ */
+ TEvhttpServer(boost::shared_ptr<TAsyncBufferProcessor> processor, int port);
+
+ ~TEvhttpServer();
+
+ static void request(struct evhttp_request* req, void* self);
+ int serve();
+
+ struct event_base* getEventBase();
+
+ private:
+ struct RequestContext;
+
+ void process(struct evhttp_request* req);
+ void complete(RequestContext* ctx, bool success);
+
+ boost::shared_ptr<TAsyncBufferProcessor> processor_;
+ struct event_base* eb_;
+ struct evhttp* eh_;
+};
+
+}}} // apache::thrift::async
+
+#endif // #ifndef _THRIFT_TEVHTTP_SERVER_H_
http://git-wip-us.apache.org/repos/asf/airavata/blob/f891b7dc/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/concurrency/BoostMonitor.cpp
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/concurrency/BoostMonitor.cpp b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/concurrency/BoostMonitor.cpp
new file mode 100644
index 0000000..1027157
--- /dev/null
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/concurrency/BoostMonitor.cpp
@@ -0,0 +1,211 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <thrift/thrift-config.h>
+
+#include <thrift/concurrency/Monitor.h>
+#include <thrift/concurrency/Exception.h>
+#include <thrift/concurrency/Util.h>
+#include <thrift/transport/PlatformSocket.h>
+#include <assert.h>
+
+#include <boost/scoped_ptr.hpp>
+#include <boost/thread.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+namespace apache { namespace thrift { namespace concurrency {
+
+/**
+ * Monitor implementation using the boost thread library
+ *
+ * @version $Id:$
+ */
+class Monitor::Impl : public boost::condition_variable_any {
+
+ public:
+
+ Impl()
+ : ownedMutex_(new Mutex()),
+ mutex_(NULL) {
+ init(ownedMutex_.get());
+ }
+
+ Impl(Mutex* mutex)
+ : mutex_(NULL) {
+ init(mutex);
+ }
+
+ Impl(Monitor* monitor)
+ : mutex_(NULL) {
+ init(&(monitor->mutex()));
+ }
+
+ Mutex& mutex() { return *mutex_; }
+ void lock() { mutex().lock(); }
+ void unlock() { mutex().unlock(); }
+
+ /**
+ * Exception-throwing version of waitForTimeRelative(), called simply
+ * wait(int64) for historical reasons. Timeout is in milliseconds.
+ *
+ * If the condition occurs, this function returns cleanly; on timeout or
+ * error an exception is thrown.
+ */
+ void wait(int64_t timeout_ms) {
+ int result = waitForTimeRelative(timeout_ms);
+ if (result == THRIFT_ETIMEDOUT) {
+ throw TimedOutException();
+ } else if (result != 0) {
+ throw TException(
+ "Monitor::wait() failed");
+ }
+ }
+
+ /**
+ * Waits until the specified timeout in milliseconds for the condition to
+ * occur, or waits forever if timeout_ms == 0.
+ *
+ * Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
+ */
+ int waitForTimeRelative(int64_t timeout_ms) {
+ if (timeout_ms == 0LL) {
+ return waitForever();
+ }
+
+ assert(mutex_);
+ boost::timed_mutex* mutexImpl =
+ reinterpret_cast<boost::timed_mutex*>(mutex_->getUnderlyingImpl());
+ assert(mutexImpl);
+
+ boost::timed_mutex::scoped_lock lock(*mutexImpl, boost::adopt_lock);
+ int res = timed_wait(lock, boost::get_system_time()+boost::posix_time::milliseconds(timeout_ms)) ? 0 : THRIFT_ETIMEDOUT;
+ lock.release();
+ return res;
+ }
+
+ /**
+ * Waits until the absolute time specified using struct THRIFT_TIMESPEC.
+ * Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
+ */
+ int waitForTime(const THRIFT_TIMESPEC* abstime) {
+ struct timeval temp;
+ temp.tv_sec = static_cast<long>(abstime->tv_sec);
+ temp.tv_usec = static_cast<long>(abstime->tv_nsec) / 1000;
+ return waitForTime(&temp);
+ }
+
+ /**
+ * Waits until the absolute time specified using struct timeval.
+ * Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
+ */
+ int waitForTime(const struct timeval* abstime) {
+ assert(mutex_);
+ boost::timed_mutex* mutexImpl =
+ static_cast<boost::timed_mutex*>(mutex_->getUnderlyingImpl());
+ assert(mutexImpl);
+
+ struct timeval currenttime;
+ Util::toTimeval(currenttime, Util::currentTime());
+
+ long tv_sec = static_cast<long>(abstime->tv_sec - currenttime.tv_sec);
+ long tv_usec = static_cast<long>(abstime->tv_usec - currenttime.tv_usec);
+ if(tv_sec < 0)
+ tv_sec = 0;
+ if(tv_usec < 0)
+ tv_usec = 0;
+
+ boost::timed_mutex::scoped_lock lock(*mutexImpl, boost::adopt_lock);
+ int res = timed_wait(lock, boost::get_system_time() +
+ boost::posix_time::seconds(tv_sec) +
+ boost::posix_time::microseconds(tv_usec)
+ ) ? 0 : THRIFT_ETIMEDOUT;
+ lock.release();
+ return res;
+ }
+
+ /**
+ * Waits forever until the condition occurs.
+ * Returns 0 if condition occurs, or an error code otherwise.
+ */
+ int waitForever() {
+ assert(mutex_);
+ boost::timed_mutex* mutexImpl =
+ reinterpret_cast<boost::timed_mutex*>(mutex_->getUnderlyingImpl());
+ assert(mutexImpl);
+
+ boost::timed_mutex::scoped_lock lock(*mutexImpl, boost::adopt_lock);
+ ((boost::condition_variable_any*)this)->wait(lock);
+ lock.release();
+ return 0;
+ }
+
+
+ void notify() {
+ notify_one();
+ }
+
+ void notifyAll() {
+ notify_all();
+ }
+
+ private:
+
+ void init(Mutex* mutex) {
+ mutex_ = mutex;
+ }
+
+ boost::scoped_ptr<Mutex> ownedMutex_;
+ Mutex* mutex_;
+};
+
+Monitor::Monitor() : impl_(new Monitor::Impl()) {}
+Monitor::Monitor(Mutex* mutex) : impl_(new Monitor::Impl(mutex)) {}
+Monitor::Monitor(Monitor* monitor) : impl_(new Monitor::Impl(monitor)) {}
+
+Monitor::~Monitor() { delete impl_; }
+
+Mutex& Monitor::mutex() const { return const_cast<Monitor::Impl*>(impl_)->mutex(); }
+
+void Monitor::lock() const { const_cast<Monitor::Impl*>(impl_)->lock(); }
+
+void Monitor::unlock() const { const_cast<Monitor::Impl*>(impl_)->unlock(); }
+
+void Monitor::wait(int64_t timeout) const { const_cast<Monitor::Impl*>(impl_)->wait(timeout); }
+
+int Monitor::waitForTime(const THRIFT_TIMESPEC* abstime) const {
+ return const_cast<Monitor::Impl*>(impl_)->waitForTime(abstime);
+}
+
+int Monitor::waitForTime(const timeval* abstime) const {
+ return const_cast<Monitor::Impl*>(impl_)->waitForTime(abstime);
+}
+
+int Monitor::waitForTimeRelative(int64_t timeout_ms) const {
+ return const_cast<Monitor::Impl*>(impl_)->waitForTimeRelative(timeout_ms);
+}
+
+int Monitor::waitForever() const {
+ return const_cast<Monitor::Impl*>(impl_)->waitForever();
+}
+
+void Monitor::notify() const { const_cast<Monitor::Impl*>(impl_)->notify(); }
+
+void Monitor::notifyAll() const { const_cast<Monitor::Impl*>(impl_)->notifyAll(); }
+
+}}} // apache::thrift::concurrency
http://git-wip-us.apache.org/repos/asf/airavata/blob/f891b7dc/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/concurrency/BoostMutex.cpp
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/concurrency/BoostMutex.cpp b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/concurrency/BoostMutex.cpp
new file mode 100644
index 0000000..eb0c3c1
--- /dev/null
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/concurrency/BoostMutex.cpp
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <thrift/thrift-config.h>
+
+#include <thrift/concurrency/Mutex.h>
+#include <thrift/concurrency/Util.h>
+
+#include <cassert>
+#include <boost/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+namespace apache { namespace thrift { namespace concurrency {
+
+/**
+ * Implementation of Mutex class using boost interprocess mutex
+ *
+ * @version $Id:$
+ */
+class Mutex::impl : public boost::timed_mutex {
+};
+
+Mutex::Mutex(Initializer init) : impl_(new Mutex::impl()) {}
+
+void* Mutex::getUnderlyingImpl() const { return impl_.get(); }
+
+void Mutex::lock() const { impl_->lock(); }
+
+bool Mutex::trylock() const { return impl_->try_lock(); }
+
+bool Mutex::timedlock(int64_t ms) const { return impl_->timed_lock(boost::get_system_time()+boost::posix_time::milliseconds(ms)); }
+
+void Mutex::unlock() const { impl_->unlock(); }
+
+void Mutex::DEFAULT_INITIALIZER(void* arg) {
+}
+
+}}} // apache::thrift::concurrency
+
http://git-wip-us.apache.org/repos/asf/airavata/blob/f891b7dc/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/concurrency/BoostThreadFactory.cpp
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/concurrency/BoostThreadFactory.cpp b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/concurrency/BoostThreadFactory.cpp
new file mode 100644
index 0000000..decacce
--- /dev/null
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/concurrency/BoostThreadFactory.cpp
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <thrift/thrift-config.h>
+
+#include <thrift/concurrency/BoostThreadFactory.h>
+#include <thrift/concurrency/Exception.h>
+
+#include <cassert>
+
+#include <boost/weak_ptr.hpp>
+#include <boost/thread.hpp>
+
+namespace apache { namespace thrift { namespace concurrency {
+
+using boost::shared_ptr;
+using boost::weak_ptr;
+
+/**
+ * The boost thread class.
+ *
+ * @version $Id:$
+ */
+class BoostThread: public Thread {
+ public:
+
+ enum STATE {
+ uninitialized,
+ starting,
+ started,
+ stopping,
+ stopped
+ };
+
+ static void* threadMain(void* arg);
+
+ private:
+ std::auto_ptr<boost::thread> thread_;
+ STATE state_;
+ weak_ptr<BoostThread> self_;
+ bool detached_;
+
+ public:
+
+ BoostThread(bool detached, shared_ptr<Runnable> runnable) :
+ state_(uninitialized),
+ detached_(detached) {
+ this->Thread::runnable(runnable);
+ }
+
+ ~BoostThread() {
+ if(!detached_) {
+ try {
+ join();
+ } catch(...) {
+ // We're really hosed.
+ }
+ }
+ }
+
+ void start() {
+ if (state_ != uninitialized) {
+ return;
+ }
+
+ // Create reference
+ shared_ptr<BoostThread>* selfRef = new shared_ptr<BoostThread>();
+ *selfRef = self_.lock();
+
+ state_ = starting;
+
+ thread_ = std::auto_ptr<boost::thread>(new boost::thread(boost::bind(threadMain, (void*)selfRef)));
+
+ if(detached_)
+ thread_->detach();
+ }
+
+ void join() {
+ if (!detached_ && state_ != uninitialized) {
+ thread_->join();
+ }
+ }
+
+ Thread::id_t getId() {
+ return thread_.get() ? thread_->get_id() : boost::thread::id();
+ }
+
+ shared_ptr<Runnable> runnable() const { return Thread::runnable(); }
+
+ void runnable(shared_ptr<Runnable> value) { Thread::runnable(value); }
+
+ void weakRef(shared_ptr<BoostThread> self) {
+ assert(self.get() == this);
+ self_ = weak_ptr<BoostThread>(self);
+ }
+};
+
+void* BoostThread::threadMain(void* arg) {
+ shared_ptr<BoostThread> thread = *(shared_ptr<BoostThread>*)arg;
+ delete reinterpret_cast<shared_ptr<BoostThread>*>(arg);
+
+ if (!thread) {
+ return (void*)0;
+ }
+
+ if (thread->state_ != starting) {
+ return (void*)0;
+ }
+
+ thread->state_ = started;
+ thread->runnable()->run();
+
+ if (thread->state_ != stopping && thread->state_ != stopped) {
+ thread->state_ = stopping;
+ }
+ return (void*)0;
+}
+
+/**
+ * POSIX Thread factory implementation
+ */
+class BoostThreadFactory::Impl {
+
+ private:
+ bool detached_;
+
+ public:
+
+ Impl(bool detached) :
+ detached_(detached) {}
+
+ /**
+ * Creates a new POSIX thread to run the runnable object
+ *
+ * @param runnable A runnable object
+ */
+ shared_ptr<Thread> newThread(shared_ptr<Runnable> runnable) const {
+ shared_ptr<BoostThread> result = shared_ptr<BoostThread>(new BoostThread(detached_, runnable));
+ result->weakRef(result);
+ runnable->thread(result);
+ return result;
+ }
+
+ bool isDetached() const { return detached_; }
+
+ void setDetached(bool value) { detached_ = value; }
+
+ Thread::id_t getCurrentThreadId() const {
+ return boost::this_thread::get_id();
+ }
+};
+
+BoostThreadFactory::BoostThreadFactory(bool detached) :
+ impl_(new BoostThreadFactory::Impl(detached)) {}
+
+shared_ptr<Thread> BoostThreadFactory::newThread(shared_ptr<Runnable> runnable) const { return impl_->newThread(runnable); }
+
+bool BoostThreadFactory::isDetached() const { return impl_->isDetached(); }
+
+void BoostThreadFactory::setDetached(bool value) { impl_->setDetached(value); }
+
+Thread::id_t BoostThreadFactory::getCurrentThreadId() const { return impl_->getCurrentThreadId(); }
+
+}}} // apache::thrift::concurrency
http://git-wip-us.apache.org/repos/asf/airavata/blob/f891b7dc/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/concurrency/BoostThreadFactory.h
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/concurrency/BoostThreadFactory.h b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/concurrency/BoostThreadFactory.h
new file mode 100644
index 0000000..6a236d3
--- /dev/null
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/concurrency/BoostThreadFactory.h
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _THRIFT_CONCURRENCY_BOOSTTHREADFACTORY_H_
+#define _THRIFT_CONCURRENCY_BOOSTTHREADFACTORY_H_ 1
+
+#include <thrift/concurrency/Thread.h>
+
+#include <boost/shared_ptr.hpp>
+
+namespace apache { namespace thrift { namespace concurrency {
+
+/**
+ * A thread factory to create posix threads
+ *
+ * @version $Id:$
+ */
+class BoostThreadFactory : public ThreadFactory {
+
+ public:
+
+ /**
+ * Boost thread factory. All threads created by a factory are reference-counted
+ * via boost::shared_ptr and boost::weak_ptr. The factory guarantees that threads and
+ * the Runnable tasks they host will be properly cleaned up once the last strong reference
+ * to both is given up.
+ *
+ * Threads are created with the specified boost policy, priority, stack-size. A detachable thread is not
+ * joinable.
+ *
+ * By default threads are not joinable.
+ */
+
+ BoostThreadFactory(bool detached=true);
+
+ // From ThreadFactory;
+ boost::shared_ptr<Thread> newThread(boost::shared_ptr<Runnable> runnable) const;
+
+ // From ThreadFactory;
+ Thread::id_t getCurrentThreadId() const;
+
+ /**
+ * Sets detached mode of threads
+ */
+ virtual void setDetached(bool detached);
+
+ /**
+ * Gets current detached mode
+ */
+ virtual bool isDetached() const;
+
+private:
+ class Impl;
+ boost::shared_ptr<Impl> impl_;
+};
+
+}}} // apache::thrift::concurrency
+
+#endif // #ifndef _THRIFT_CONCURRENCY_BOOSTTHREADFACTORY_H_
http://git-wip-us.apache.org/repos/asf/airavata/blob/f891b7dc/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/concurrency/Exception.h
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/concurrency/Exception.h b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/concurrency/Exception.h
new file mode 100644
index 0000000..c62f116
--- /dev/null
+++ b/airavata-api/airavata-client-sdks/airavata-cpp-sdk/src/main/resources/lib/thrift/concurrency/Exception.h
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _THRIFT_CONCURRENCY_EXCEPTION_H_
+#define _THRIFT_CONCURRENCY_EXCEPTION_H_ 1
+
+#include <exception>
+#include <thrift/Thrift.h>
+
+namespace apache { namespace thrift { namespace concurrency {
+
+class NoSuchTaskException : public apache::thrift::TException {};
+
+class UncancellableTaskException : public apache::thrift::TException {};
+
+class InvalidArgumentException : public apache::thrift::TException {};
+
+class IllegalStateException : public apache::thrift::TException {
+public:
+ IllegalStateException() {}
+ IllegalStateException(const std::string& message) : TException(message) {}
+};
+
+class TimedOutException : public apache::thrift::TException {
+public:
+ TimedOutException():TException("TimedOutException"){};
+ TimedOutException(const std::string& message ) :
+ TException(message) {}
+};
+
+class TooManyPendingTasksException : public apache::thrift::TException {
+public:
+ TooManyPendingTasksException():TException("TooManyPendingTasksException"){};
+ TooManyPendingTasksException(const std::string& message ) :
+ TException(message) {}
+};
+
+class SystemResourceException : public apache::thrift::TException {
+public:
+ SystemResourceException() {}
+
+ SystemResourceException(const std::string& message) :
+ TException(message) {}
+};
+
+}}} // apache::thrift::concurrency
+
+#endif // #ifndef _THRIFT_CONCURRENCY_EXCEPTION_H_