forked from pool/thrift
Accepting request 200385 from home:dstoecker
Framework library not yet in official OBS repos. Taken from home:jblunck:messaging. OBS-URL: https://build.opensuse.org/request/show/200385 OBS-URL: https://build.opensuse.org/package/show/devel:tools/thrift?expand=0&rev=1
This commit is contained in:
commit
e2cbd2fdb3
23
.gitattributes
vendored
Normal file
23
.gitattributes
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
## Default LFS
|
||||
*.7z filter=lfs diff=lfs merge=lfs -text
|
||||
*.bsp filter=lfs diff=lfs merge=lfs -text
|
||||
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
||||
*.gem filter=lfs diff=lfs merge=lfs -text
|
||||
*.gz filter=lfs diff=lfs merge=lfs -text
|
||||
*.jar filter=lfs diff=lfs merge=lfs -text
|
||||
*.lz filter=lfs diff=lfs merge=lfs -text
|
||||
*.lzma filter=lfs diff=lfs merge=lfs -text
|
||||
*.obscpio filter=lfs diff=lfs merge=lfs -text
|
||||
*.oxt filter=lfs diff=lfs merge=lfs -text
|
||||
*.pdf filter=lfs diff=lfs merge=lfs -text
|
||||
*.png filter=lfs diff=lfs merge=lfs -text
|
||||
*.rpm filter=lfs diff=lfs merge=lfs -text
|
||||
*.tbz filter=lfs diff=lfs merge=lfs -text
|
||||
*.tbz2 filter=lfs diff=lfs merge=lfs -text
|
||||
*.tgz filter=lfs diff=lfs merge=lfs -text
|
||||
*.ttf filter=lfs diff=lfs merge=lfs -text
|
||||
*.txz filter=lfs diff=lfs merge=lfs -text
|
||||
*.whl filter=lfs diff=lfs merge=lfs -text
|
||||
*.xz filter=lfs diff=lfs merge=lfs -text
|
||||
*.zip filter=lfs diff=lfs merge=lfs -text
|
||||
*.zst filter=lfs diff=lfs merge=lfs -text
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.osc
|
48
0001-Add-missing-limits-header.patch
Normal file
48
0001-Add-missing-limits-header.patch
Normal file
@ -0,0 +1,48 @@
|
||||
Index: thrift-0.9.0/lib/cpp/src/thrift/protocol/TDebugProtocol.cpp
|
||||
===================================================================
|
||||
--- thrift-0.9.0.orig/lib/cpp/src/thrift/protocol/TDebugProtocol.cpp 2012-12-02 07:53:16.470513572 -0600
|
||||
+++ thrift-0.9.0/lib/cpp/src/thrift/protocol/TDebugProtocol.cpp 2012-12-02 07:54:47.362509517 -0600
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <stdexcept>
|
||||
+#include <limits>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
Index: thrift-0.9.0/lib/cpp/src/thrift/protocol/TDenseProtocol.cpp
|
||||
===================================================================
|
||||
--- thrift-0.9.0.orig/lib/cpp/src/thrift/protocol/TDenseProtocol.cpp 2012-12-02 07:52:51.706514677 -0600
|
||||
+++ thrift-0.9.0/lib/cpp/src/thrift/protocol/TDenseProtocol.cpp 2012-12-02 07:54:06.918511327 -0600
|
||||
@@ -89,6 +89,7 @@
|
||||
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#include <stdint.h>
|
||||
+#include <limits>
|
||||
#include <thrift/protocol/TDenseProtocol.h>
|
||||
#include <thrift/TReflectionLocal.h>
|
||||
|
||||
Index: thrift-0.9.0/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp
|
||||
===================================================================
|
||||
--- thrift-0.9.0.orig/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp 2012-12-02 07:53:04.218514119 -0600
|
||||
+++ thrift-0.9.0/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp 2012-12-02 07:54:24.122510554 -0600
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "TJSONProtocol.h"
|
||||
|
||||
#include <math.h>
|
||||
+#include <limits>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include "TBase64Utils.h"
|
||||
#include <thrift/transport/TTransportException.h>
|
||||
Index: thrift-0.9.0/lib/cpp/src/thrift/transport/THttpClient.cpp
|
||||
===================================================================
|
||||
--- thrift-0.9.0.orig/lib/cpp/src/thrift/transport/THttpClient.cpp 2012-12-02 07:53:24.610513212 -0600
|
||||
+++ thrift-0.9.0/lib/cpp/src/thrift/transport/THttpClient.cpp 2012-12-02 07:53:46.750512234 -0600
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
+#include <limits>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include <thrift/transport/THttpClient.h>
|
981
0002-TNonblockingServer-TLibEventTransport.patch
Normal file
981
0002-TNonblockingServer-TLibEventTransport.patch
Normal file
@ -0,0 +1,981 @@
|
||||
Index: thrift-0.9.0/lib/cpp/Makefile.am
|
||||
===================================================================
|
||||
--- thrift-0.9.0.orig/lib/cpp/Makefile.am 2012-10-12 02:58:06.000000000 +0200
|
||||
+++ thrift-0.9.0/lib/cpp/Makefile.am 2013-08-15 16:53:40.000000000 +0200
|
||||
@@ -181,7 +181,8 @@
|
||||
src/thrift/transport/TTransportUtils.h \
|
||||
src/thrift/transport/TBufferTransports.h \
|
||||
src/thrift/transport/TShortReadTransport.h \
|
||||
- src/thrift/transport/TZlibTransport.h
|
||||
+ src/thrift/transport/TZlibTransport.h \
|
||||
+ src/thrift/transport/TLibEventTransport.h
|
||||
|
||||
include_serverdir = $(include_thriftdir)/server
|
||||
include_server_HEADERS = \
|
||||
Index: thrift-0.9.0/lib/cpp/Makefile.in
|
||||
===================================================================
|
||||
--- thrift-0.9.0.orig/lib/cpp/Makefile.in 2012-10-12 02:59:49.000000000 +0200
|
||||
+++ thrift-0.9.0/lib/cpp/Makefile.in 2013-08-15 16:53:40.000000000 +0200
|
||||
@@ -618,7 +618,8 @@
|
||||
src/thrift/transport/TTransportUtils.h \
|
||||
src/thrift/transport/TBufferTransports.h \
|
||||
src/thrift/transport/TShortReadTransport.h \
|
||||
- src/thrift/transport/TZlibTransport.h
|
||||
+ src/thrift/transport/TZlibTransport.h \
|
||||
+ src/thrift/transport/TLibEventTransport.h
|
||||
|
||||
include_serverdir = $(include_thriftdir)/server
|
||||
include_server_HEADERS = \
|
||||
Index: thrift-0.9.0/lib/cpp/src/thrift/server/TNonblockingServer.cpp
|
||||
===================================================================
|
||||
--- thrift-0.9.0.orig/lib/cpp/src/thrift/server/TNonblockingServer.cpp 2012-10-12 02:58:06.000000000 +0200
|
||||
+++ thrift-0.9.0/lib/cpp/src/thrift/server/TNonblockingServer.cpp 2013-08-15 17:11:07.000000000 +0200
|
||||
@@ -25,10 +25,13 @@
|
||||
|
||||
#include "TNonblockingServer.h"
|
||||
#include <thrift/concurrency/Exception.h>
|
||||
-#include <thrift/transport/TSocket.h>
|
||||
+#include <thrift/transport/TLibEventTransport.h>
|
||||
#include <thrift/concurrency/PlatformThreadFactory.h>
|
||||
|
||||
+#include <boost/bind.hpp>
|
||||
+
|
||||
#include <iostream>
|
||||
+#include <queue>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
@@ -76,13 +79,6 @@
|
||||
using apache::thrift::transport::TTransportException;
|
||||
using boost::shared_ptr;
|
||||
|
||||
-/// Three states for sockets: recv frame size, recv data, and send mode
|
||||
-enum TSocketState {
|
||||
- SOCKET_RECV_FRAMING,
|
||||
- SOCKET_RECV,
|
||||
- SOCKET_SEND
|
||||
-};
|
||||
-
|
||||
/**
|
||||
* Five states for the nonblocking server:
|
||||
* 1) initialize
|
||||
@@ -93,7 +89,6 @@
|
||||
*/
|
||||
enum TAppState {
|
||||
APP_INIT,
|
||||
- APP_READ_FRAME_SIZE,
|
||||
APP_READ_REQUEST,
|
||||
APP_WAIT_TASK,
|
||||
APP_SEND_RESULT,
|
||||
@@ -116,7 +111,7 @@
|
||||
boost::shared_ptr<TProcessor> processor_;
|
||||
|
||||
/// Object wrapping network socket
|
||||
- boost::shared_ptr<TSocket> tSocket_;
|
||||
+ boost::shared_ptr<TLibEventTransport> tSocket_;
|
||||
|
||||
/// Libevent object
|
||||
struct event event_;
|
||||
@@ -124,8 +119,8 @@
|
||||
/// Libevent flags
|
||||
short eventFlags_;
|
||||
|
||||
- /// Socket mode
|
||||
- TSocketState socketState_;
|
||||
+ /// Tells whether the frame size was read completely.
|
||||
+ bool readFrameSize_;
|
||||
|
||||
/// Application state
|
||||
TAppState appState_;
|
||||
@@ -142,15 +137,12 @@
|
||||
/// Read buffer size
|
||||
uint32_t readBufferSize_;
|
||||
|
||||
- /// Write buffer
|
||||
- uint8_t* writeBuffer_;
|
||||
-
|
||||
- /// Write buffer size
|
||||
- uint32_t writeBufferSize_;
|
||||
-
|
||||
/// How far through writing are we?
|
||||
uint32_t writeBufferPos_;
|
||||
|
||||
+ /// Write position for external events
|
||||
+ uint externalWriteBufferPos_;
|
||||
+
|
||||
/// Largest size of write buffer seen since buffer was constructed
|
||||
size_t largestWriteBufferSize_;
|
||||
|
||||
@@ -169,6 +161,9 @@
|
||||
/// Transport that processor writes to
|
||||
boost::shared_ptr<TMemoryBuffer> outputTransport_;
|
||||
|
||||
+ /// Transport that processes writes from an external libevent source.
|
||||
+ boost::shared_ptr<TMemoryBuffer> externalTransport_;
|
||||
+
|
||||
/// extra transport generated by transport factory (e.g. BufferedRouterTransport)
|
||||
boost::shared_ptr<TTransport> factoryInputTransport_;
|
||||
boost::shared_ptr<TTransport> factoryOutputTransport_;
|
||||
@@ -185,6 +180,16 @@
|
||||
/// Thrift call context, if any
|
||||
void *connectionContext_;
|
||||
|
||||
+ /// Node for queuing write requests from internal and external sources.
|
||||
+ typedef std::pair<bool, uint32_t> WriteRequest;
|
||||
+
|
||||
+ /// Queue with write requests from outputTransport_ and externalTransport_.
|
||||
+ std::queue<WriteRequest> writeRequests_;
|
||||
+
|
||||
+ /// Queues a write request for internal or external buffer and notifies
|
||||
+ /// libevent.
|
||||
+ void scheduleWrite(bool externalBuffer, uint32_t len);
|
||||
+
|
||||
/// Go into read mode
|
||||
void setRead() {
|
||||
setFlags(EV_READ | EV_PERSIST);
|
||||
@@ -195,6 +200,11 @@
|
||||
setFlags(EV_WRITE | EV_PERSIST);
|
||||
}
|
||||
|
||||
+ /// Resets write mode after all write requests were send.
|
||||
+ void clearWrite() {
|
||||
+ clearFlags(EV_WRITE);
|
||||
+ }
|
||||
+
|
||||
/// Set socket idle
|
||||
void setIdle() {
|
||||
setFlags(0);
|
||||
@@ -208,12 +218,37 @@
|
||||
void setFlags(short eventFlags);
|
||||
|
||||
/**
|
||||
+ * Clear event flags for this connection.
|
||||
+ *
|
||||
+ * @param eventFlags flags we pass to libevent for the connection.
|
||||
+ */
|
||||
+ void clearFlags(short eventFlags);
|
||||
+
|
||||
+ /**
|
||||
* Libevent handler called (via our static wrapper) when the connection
|
||||
* socket had something happen. Rather than use the flags libevent passed,
|
||||
* we use the connection state to determine whether we need to read or
|
||||
* write the socket.
|
||||
*/
|
||||
- void workSocket();
|
||||
+ void workSocket(short ev_type);
|
||||
+
|
||||
+ /**
|
||||
+ * Reads frame size and message from socket.
|
||||
+ */
|
||||
+ bool readSocket();
|
||||
+
|
||||
+ /**
|
||||
+ * Writes as many queued requests as possible
|
||||
+ */
|
||||
+ bool writeSocket();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the frame size for a message that was written into a TMemoryBuffer.
|
||||
+ *
|
||||
+ * @param buf buffer including a new message at the end
|
||||
+ * @param msgSize Size of the message including frame header
|
||||
+ */
|
||||
+ void setFrameSize(TMemoryBuffer& buf, uint32_t msgSize);
|
||||
|
||||
/// Close this connection and free or reset its resources.
|
||||
void close();
|
||||
@@ -236,7 +271,16 @@
|
||||
inputTransport_.reset(new TMemoryBuffer(readBuffer_, readBufferSize_));
|
||||
outputTransport_.reset(new TMemoryBuffer(
|
||||
server_->getWriteBufferDefaultSize()));
|
||||
- tSocket_.reset(new TSocket());
|
||||
+ externalTransport_.reset(new TMemoryBuffer(
|
||||
+ server_->getWriteBufferDefaultSize()));
|
||||
+
|
||||
+ boost::shared_ptr<TProtocol> externalProtocol =
|
||||
+ server_->getOutputProtocolFactory()->getProtocol(externalTransport_);
|
||||
+
|
||||
+ tSocket_.reset(new TLibEventTransport(
|
||||
+ externalProtocol,
|
||||
+ boost::bind(&TConnection::beginExternalWriteEvent, this),
|
||||
+ boost::bind(&TConnection::endExternalWriteEvent, this)));
|
||||
init(socket, ioThread, addr, addrLen);
|
||||
}
|
||||
|
||||
@@ -244,6 +288,18 @@
|
||||
std::free(readBuffer_);
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * Callback for TLibEventTransport to write 4 bytes for the frame header
|
||||
+ * into externalTransport_.
|
||||
+ */
|
||||
+ void beginExternalWriteEvent();
|
||||
+
|
||||
+ /**
|
||||
+ * Callback for TLibEventTransport to calculate the frame size and notifiy
|
||||
+ * libevent for writting.
|
||||
+ */
|
||||
+ void endExternalWriteEvent();
|
||||
+
|
||||
/**
|
||||
* Check buffers against any size limits and shrink it if exceeded.
|
||||
*
|
||||
@@ -267,13 +323,13 @@
|
||||
* C-callable event handler for connection events. Provides a callback
|
||||
* that libevent can understand which invokes connection_->workSocket().
|
||||
*
|
||||
- * @param fd the descriptor the event occurred on.
|
||||
- * @param which the flags associated with the event.
|
||||
- * @param v void* callback arg where we placed TConnection's "this".
|
||||
+ * @param fd the descriptor the event occurred on.
|
||||
+ * @param ev_type the flags associated with the event.
|
||||
+ * @param v void* callback arg where we placed TConnection's "this".
|
||||
*/
|
||||
- static void eventHandler(evutil_socket_t fd, short /* which */, void* v) {
|
||||
+ static void eventHandler(evutil_socket_t fd, short ev_type, void* v) {
|
||||
assert(fd == ((TConnection*)v)->getTSocket()->getSocketFD());
|
||||
- ((TConnection*)v)->workSocket();
|
||||
+ ((TConnection*)v)->workSocket(ev_type);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -394,6 +450,7 @@
|
||||
socklen_t addrLen) {
|
||||
tSocket_->setSocketFD(socket);
|
||||
tSocket_->setCachedAddress(addr, addrLen);
|
||||
+ tSocket_->setEventBase(*(ioThread->getEventBase()));
|
||||
|
||||
ioThread_ = ioThread;
|
||||
server_ = ioThread->getServer();
|
||||
@@ -403,12 +460,9 @@
|
||||
readBufferPos_ = 0;
|
||||
readWant_ = 0;
|
||||
|
||||
- writeBuffer_ = NULL;
|
||||
- writeBufferSize_ = 0;
|
||||
- writeBufferPos_ = 0;
|
||||
largestWriteBufferSize_ = 0;
|
||||
|
||||
- socketState_ = SOCKET_RECV_FRAMING;
|
||||
+ readFrameSize_ = true;
|
||||
callsForResize_ = 0;
|
||||
|
||||
// get input/transports
|
||||
@@ -436,12 +490,29 @@
|
||||
processor_ = server_->getProcessor(inputProtocol_, outputProtocol_, tSocket_);
|
||||
}
|
||||
|
||||
-void TNonblockingServer::TConnection::workSocket() {
|
||||
- int got=0, left=0, sent=0;
|
||||
+void TNonblockingServer::TConnection::workSocket(short ev_type) {
|
||||
+
|
||||
+ if (ev_type & EV_READ) {
|
||||
+ if (!readSocket()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (ev_type & EV_WRITE) {
|
||||
+ if (!writeSocket()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (ev_type & ~(EV_READ | EV_WRITE))
|
||||
+ GlobalOutput.printf("TConnection::workSocket: unexpected event type %d",
|
||||
+ ev_type & ~(EV_READ | EV_WRITE));
|
||||
+}
|
||||
+
|
||||
+bool TNonblockingServer::TConnection::readSocket() {
|
||||
uint32_t fetch = 0;
|
||||
|
||||
- switch (socketState_) {
|
||||
- case SOCKET_RECV_FRAMING:
|
||||
+ if (readFrameSize_) {
|
||||
union {
|
||||
uint8_t buf[sizeof(uint32_t)];
|
||||
uint32_t size;
|
||||
@@ -457,20 +528,22 @@
|
||||
if (fetch == 0) {
|
||||
// Whenever we get here it means a remote disconnect
|
||||
close();
|
||||
- return;
|
||||
+
|
||||
+ return false;
|
||||
}
|
||||
readBufferPos_ += fetch;
|
||||
- } catch (TTransportException& te) {
|
||||
- GlobalOutput.printf("TConnection::workSocket(): %s", te.what());
|
||||
+ } catch(TTransportException& te) {
|
||||
+ GlobalOutput.printf("TConnection::readSocket(): %s", te.what());
|
||||
close();
|
||||
|
||||
- return;
|
||||
+ return false;
|
||||
}
|
||||
|
||||
if (readBufferPos_ < sizeof(framing.size)) {
|
||||
// more needed before frame size is known -- save what we have so far
|
||||
readWant_ = framing.size;
|
||||
- return;
|
||||
+
|
||||
+ return true;
|
||||
}
|
||||
|
||||
readWant_ = ntohl(framing.size);
|
||||
@@ -483,84 +556,154 @@
|
||||
readWant_, server_->getMaxFrameSize(),
|
||||
tSocket_->getSocketInfo().c_str());
|
||||
close();
|
||||
- return;
|
||||
- }
|
||||
- // size known; now get the rest of the frame
|
||||
- transition();
|
||||
- return;
|
||||
-
|
||||
- case SOCKET_RECV:
|
||||
- // It is an error to be in this state if we already have all the data
|
||||
- assert(readBufferPos_ < readWant_);
|
||||
|
||||
- try {
|
||||
- // Read from the socket
|
||||
- fetch = readWant_ - readBufferPos_;
|
||||
- got = tSocket_->read(readBuffer_ + readBufferPos_, fetch);
|
||||
+ return false;
|
||||
}
|
||||
- catch (TTransportException& te) {
|
||||
- GlobalOutput.printf("TConnection::workSocket(): %s", te.what());
|
||||
- close();
|
||||
|
||||
- return;
|
||||
- }
|
||||
+ readFrameSize_ = false;
|
||||
|
||||
- if (got > 0) {
|
||||
- // Move along in the buffer
|
||||
- readBufferPos_ += got;
|
||||
-
|
||||
- // Check that we did not overdo it
|
||||
- assert(readBufferPos_ <= readWant_);
|
||||
-
|
||||
- // We are done reading, move onto the next state
|
||||
- if (readBufferPos_ == readWant_) {
|
||||
- transition();
|
||||
+ // We just read the request length
|
||||
+ // Double the buffer size until it is big enough
|
||||
+ if (readWant_ > readBufferSize_) {
|
||||
+ if (readBufferSize_ == 0) {
|
||||
+ readBufferSize_ = 1;
|
||||
}
|
||||
- return;
|
||||
+ uint32_t newSize = readBufferSize_;
|
||||
+ while (readWant_ > newSize) {
|
||||
+ newSize *= 2;
|
||||
+ }
|
||||
+
|
||||
+ uint8_t* newBuffer = (uint8_t*)std::realloc(readBuffer_, newSize);
|
||||
+ if (newBuffer == NULL) {
|
||||
+ // nothing else to be done...
|
||||
+ throw std::bad_alloc();
|
||||
+ }
|
||||
+ readBuffer_ = newBuffer;
|
||||
+ readBufferSize_ = newSize;
|
||||
}
|
||||
|
||||
- // Whenever we get down here it means a remote disconnect
|
||||
+ readBufferPos_= 0;
|
||||
+ }
|
||||
+
|
||||
+ // size known; now get the rest of the frame
|
||||
+
|
||||
+ // It is an error to be in this state if we already have all the data
|
||||
+ assert(readBufferPos_ < readWant_);
|
||||
+
|
||||
+ uint32_t got=0;
|
||||
+
|
||||
+ try {
|
||||
+ // Read from the socket
|
||||
+ fetch = readWant_ - readBufferPos_;
|
||||
+ got = tSocket_->read(readBuffer_ + readBufferPos_, fetch);
|
||||
+ }
|
||||
+ catch (TTransportException& te) {
|
||||
+ GlobalOutput.printf("TConnection::readSocket(): %s", te.what());
|
||||
close();
|
||||
|
||||
- return;
|
||||
+ return false;
|
||||
+ }
|
||||
|
||||
- case SOCKET_SEND:
|
||||
- // Should never have position past size
|
||||
- assert(writeBufferPos_ <= writeBufferSize_);
|
||||
+ if (got > 0) {
|
||||
+ // Move along in the buffer
|
||||
+ readBufferPos_ += got;
|
||||
+
|
||||
+ // Check that we did not overdo it
|
||||
+ assert(readBufferPos_ <= readWant_);
|
||||
+
|
||||
+ // We are done reading, move onto the next state
|
||||
+ if (readBufferPos_ == readWant_) {
|
||||
+ transition();
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ // Whenever we get down here it means a remote disconnect
|
||||
+ close();
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+bool TNonblockingServer::TConnection::writeSocket() {
|
||||
+ while(writeRequests_.empty() == false) {
|
||||
+ WriteRequest& writeReq = writeRequests_.front();
|
||||
+
|
||||
+ TMemoryBuffer* transport = writeReq.first ? externalTransport_.get() :
|
||||
+ outputTransport_.get();
|
||||
+
|
||||
+ uint8_t* writeBuffer;
|
||||
+ uint32_t writeBufferSize;
|
||||
+
|
||||
+ transport->getBuffer(&writeBuffer, &writeBufferSize);
|
||||
+ transport->borrow(0, &writeBufferSize);
|
||||
+
|
||||
+ uint32_t writeSize = writeReq.second;
|
||||
+ if(writeBufferSize < writeReq.second) {
|
||||
+ GlobalOutput.printf("WARNING: Write request size %u > %u buffer size.\n",
|
||||
+ writeReq.second, writeBufferSize);
|
||||
+ writeSize = writeBufferSize;
|
||||
+ }
|
||||
|
||||
// If there is no data to send, then let us move on
|
||||
- if (writeBufferPos_ == writeBufferSize_) {
|
||||
+ if (writeBufferSize == 0) {
|
||||
GlobalOutput("WARNING: Send state with no data to send\n");
|
||||
- transition();
|
||||
- return;
|
||||
+ writeRequests_.pop();
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (writeBufferSize > largestWriteBufferSize_) {
|
||||
+ largestWriteBufferSize_ = writeBufferSize;
|
||||
}
|
||||
|
||||
+ uint32_t sent = 0;
|
||||
+
|
||||
try {
|
||||
- left = writeBufferSize_ - writeBufferPos_;
|
||||
- sent = tSocket_->write_partial(writeBuffer_ + writeBufferPos_, left);
|
||||
+ sent = tSocket_->write_partial(writeBuffer, writeSize);
|
||||
}
|
||||
- catch (TTransportException& te) {
|
||||
- GlobalOutput.printf("TConnection::workSocket(): %s ", te.what());
|
||||
+ catch(TTransportException& te) {
|
||||
+ GlobalOutput.printf("TConnection::writeSocket(): %s ", te.what());
|
||||
close();
|
||||
- return;
|
||||
+
|
||||
+ return false;
|
||||
}
|
||||
|
||||
- writeBufferPos_ += sent;
|
||||
+ // We are done!
|
||||
+ if (sent == writeBufferSize) {
|
||||
+ transport->consume(sent);
|
||||
+ writeRequests_.pop();
|
||||
+ }
|
||||
+ else if (sent > 0) {
|
||||
+ // Message was not written completely.
|
||||
+ transport->consume(sent);
|
||||
|
||||
- // Did we overdo it?
|
||||
- assert(writeBufferPos_ <= writeBufferSize_);
|
||||
+ // Adjust size in write request.
|
||||
+ writeReq.second -= sent;
|
||||
|
||||
- // We are done!
|
||||
- if (writeBufferPos_ == writeBufferSize_) {
|
||||
- transition();
|
||||
+ return true;
|
||||
}
|
||||
+ }
|
||||
|
||||
- return;
|
||||
+ // All queued requests were written, clear write flag.
|
||||
+ clearWrite();
|
||||
|
||||
- default:
|
||||
- GlobalOutput.printf("Unexpected Socket State %d", socketState_);
|
||||
- assert(0);
|
||||
+ // Verify that there's no incomplete message in the output buffers.
|
||||
+ if(outputTransport_->peek() || externalTransport_->peek())
|
||||
+ return true;
|
||||
+
|
||||
+ // it's now safe to perform buffer size housekeeping.
|
||||
+ if (server_->getResizeBufferEveryN() > 0
|
||||
+ && ++callsForResize_ >= server_->getResizeBufferEveryN()) {
|
||||
+ checkIdleBufferMemLimit(server_->getIdleReadBufferLimit(),
|
||||
+ server_->getIdleWriteBufferLimit());
|
||||
+ callsForResize_ = 0;
|
||||
}
|
||||
+
|
||||
+ // Reset write buffer position to the beginning of the buffer.
|
||||
+ outputTransport_->resetBuffer();
|
||||
+ externalTransport_->resetBuffer();
|
||||
+
|
||||
+ return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -580,9 +723,9 @@
|
||||
// We are done reading the request, package the read buffer into transport
|
||||
// and get back some data from the dispatch function
|
||||
inputTransport_->resetBuffer(readBuffer_, readBufferPos_);
|
||||
- outputTransport_->resetBuffer();
|
||||
// Prepend four bytes of blank space to the buffer so we can
|
||||
// write the frame size there later.
|
||||
+ writeBufferPos_ = outputTransport_->writeEnd();
|
||||
outputTransport_->getWritePtr(4);
|
||||
outputTransport_->wroteBytes(4);
|
||||
|
||||
@@ -615,10 +758,10 @@
|
||||
return;
|
||||
} else {
|
||||
try {
|
||||
- if (serverEventHandler_ != NULL) {
|
||||
- serverEventHandler_->processContext(connectionContext_,
|
||||
- getTSocket());
|
||||
- }
|
||||
+ if (serverEventHandler_ != NULL) {
|
||||
+ serverEventHandler_->processContext(connectionContext_,
|
||||
+ getTSocket());
|
||||
+ }
|
||||
// Invoke the processor
|
||||
processor_->process(inputProtocol_, outputProtocol_,
|
||||
connectionContext_);
|
||||
@@ -646,107 +789,36 @@
|
||||
// the writeBuffer_
|
||||
|
||||
case APP_WAIT_TASK:
|
||||
+ {
|
||||
// We have now finished processing a task and the result has been written
|
||||
// into the outputTransport_, so we grab its contents and place them into
|
||||
// the writeBuffer_ for actual writing by the libevent thread
|
||||
|
||||
server_->decrementActiveProcessors();
|
||||
- // Get the result of the operation
|
||||
- outputTransport_->getBuffer(&writeBuffer_, &writeBufferSize_);
|
||||
|
||||
- // If the function call generated return data, then move into the send
|
||||
- // state and get going
|
||||
- // 4 bytes were reserved for frame size
|
||||
- if (writeBufferSize_ > 4) {
|
||||
-
|
||||
- // Move into write state
|
||||
- writeBufferPos_ = 0;
|
||||
- socketState_ = SOCKET_SEND;
|
||||
-
|
||||
- // Put the frame size into the write buffer
|
||||
- int32_t frameSize = (int32_t)htonl(writeBufferSize_ - 4);
|
||||
- memcpy(writeBuffer_, &frameSize, 4);
|
||||
-
|
||||
- // Socket into write mode
|
||||
- appState_ = APP_SEND_RESULT;
|
||||
- setWrite();
|
||||
-
|
||||
- // Try to work the socket immediately
|
||||
- // workSocket();
|
||||
-
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- // In this case, the request was oneway and we should fall through
|
||||
- // right back into the read frame header state
|
||||
- goto LABEL_APP_INIT;
|
||||
-
|
||||
- case APP_SEND_RESULT:
|
||||
- // it's now safe to perform buffer size housekeeping.
|
||||
- if (writeBufferSize_ > largestWriteBufferSize_) {
|
||||
- largestWriteBufferSize_ = writeBufferSize_;
|
||||
- }
|
||||
- if (server_->getResizeBufferEveryN() > 0
|
||||
- && ++callsForResize_ >= server_->getResizeBufferEveryN()) {
|
||||
- checkIdleBufferMemLimit(server_->getIdleReadBufferLimit(),
|
||||
- server_->getIdleWriteBufferLimit());
|
||||
- callsForResize_ = 0;
|
||||
+ // If the processor did not write a response we have to remove again
|
||||
+ // the 4 bytes from the frame size.
|
||||
+ uint32_t writePos = outputTransport_->writeEnd();
|
||||
+ if (writePos == writeBufferPos_ + 4)
|
||||
+ outputTransport_->revertLastWrite(4);
|
||||
+ else {
|
||||
+ uint32_t size = writePos - writeBufferPos_;
|
||||
+ setFrameSize(*outputTransport_, size);
|
||||
+ scheduleWrite(false, size);
|
||||
}
|
||||
|
||||
// N.B.: We also intentionally fall through here into the INIT state!
|
||||
-
|
||||
- LABEL_APP_INIT:
|
||||
+ }
|
||||
case APP_INIT:
|
||||
|
||||
- // Clear write buffer variables
|
||||
- writeBuffer_ = NULL;
|
||||
- writeBufferPos_ = 0;
|
||||
- writeBufferSize_ = 0;
|
||||
-
|
||||
// Into read4 state we go
|
||||
- socketState_ = SOCKET_RECV_FRAMING;
|
||||
- appState_ = APP_READ_FRAME_SIZE;
|
||||
+ readFrameSize_ = true;
|
||||
+ appState_ = APP_READ_REQUEST;
|
||||
|
||||
readBufferPos_ = 0;
|
||||
|
||||
// Register read event
|
||||
setRead();
|
||||
-
|
||||
- // Try to work the socket right away
|
||||
- // workSocket();
|
||||
-
|
||||
- return;
|
||||
-
|
||||
- case APP_READ_FRAME_SIZE:
|
||||
- // We just read the request length
|
||||
- // Double the buffer size until it is big enough
|
||||
- if (readWant_ > readBufferSize_) {
|
||||
- if (readBufferSize_ == 0) {
|
||||
- readBufferSize_ = 1;
|
||||
- }
|
||||
- uint32_t newSize = readBufferSize_;
|
||||
- while (readWant_ > newSize) {
|
||||
- newSize *= 2;
|
||||
- }
|
||||
-
|
||||
- uint8_t* newBuffer = (uint8_t*)std::realloc(readBuffer_, newSize);
|
||||
- if (newBuffer == NULL) {
|
||||
- // nothing else to be done...
|
||||
- throw std::bad_alloc();
|
||||
- }
|
||||
- readBuffer_ = newBuffer;
|
||||
- readBufferSize_ = newSize;
|
||||
- }
|
||||
-
|
||||
- readBufferPos_= 0;
|
||||
-
|
||||
- // Move into read request state
|
||||
- socketState_ = SOCKET_RECV;
|
||||
- appState_ = APP_READ_REQUEST;
|
||||
-
|
||||
- // Work the socket right away
|
||||
- // workSocket();
|
||||
-
|
||||
return;
|
||||
|
||||
case APP_CLOSE_CONNECTION:
|
||||
@@ -760,9 +832,59 @@
|
||||
}
|
||||
}
|
||||
|
||||
+void TNonblockingServer::TConnection::beginExternalWriteEvent() {
|
||||
+ // Prepend four bytes of blank space to the buffer so we can
|
||||
+ // write the frame size there later.
|
||||
+ externalWriteBufferPos_ = externalTransport_->writeEnd();
|
||||
+ externalTransport_->getWritePtr(4);
|
||||
+ externalTransport_->wroteBytes(4);
|
||||
+}
|
||||
+
|
||||
+void TNonblockingServer::TConnection::endExternalWriteEvent() {
|
||||
+ // If the external function did not write anything we have to remove again
|
||||
+ // the 4 bytes from the frame size.
|
||||
+ uint32_t writePos = externalTransport_->writeEnd();
|
||||
+
|
||||
+ if (writePos == externalWriteBufferPos_ + 4)
|
||||
+ externalTransport_->revertLastWrite(4);
|
||||
+ else {
|
||||
+ uint32_t size = writePos - externalWriteBufferPos_;
|
||||
+ setFrameSize(*externalTransport_, size);
|
||||
+
|
||||
+ scheduleWrite(true, size);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void TNonblockingServer::TConnection::setFrameSize(
|
||||
+ TMemoryBuffer& buf, uint32_t size) {
|
||||
+ uint8_t* begin = buf.getWritePtr(0) - size;
|
||||
+
|
||||
+ // Put the frame size into the write buffer (subtract 4 bytes from
|
||||
+ // for frame size header).
|
||||
+ int32_t frameSize = (int32_t)htonl(size - 4);
|
||||
+ memcpy(begin, &frameSize, 4);
|
||||
+}
|
||||
+
|
||||
+void TNonblockingServer::TConnection::scheduleWrite(
|
||||
+ bool externalBuffer, uint32_t len) {
|
||||
+ if( writeRequests_.empty() ) {
|
||||
+ writeRequests_.push(WriteRequest(externalBuffer, len));
|
||||
+ setWrite();
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ WriteRequest& req = writeRequests_.back();
|
||||
+
|
||||
+ // We can extend the last write request if the buffer is the same.
|
||||
+ if(externalBuffer == req.first)
|
||||
+ req.second += len;
|
||||
+ else
|
||||
+ writeRequests_.push(WriteRequest(externalBuffer, len));
|
||||
+}
|
||||
+
|
||||
void TNonblockingServer::TConnection::setFlags(short eventFlags) {
|
||||
// Catch the do nothing case
|
||||
- if (eventFlags_ == eventFlags) {
|
||||
+ if ((eventFlags_ | eventFlags) == eventFlags_) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -775,7 +897,7 @@
|
||||
}
|
||||
|
||||
// Update in memory structure
|
||||
- eventFlags_ = eventFlags;
|
||||
+ eventFlags_ |= eventFlags;
|
||||
|
||||
// Do not call event_set if there are no flags
|
||||
if (!eventFlags_) {
|
||||
@@ -819,10 +941,43 @@
|
||||
}
|
||||
}
|
||||
|
||||
+void TNonblockingServer::TConnection::clearFlags(short eventFlags) {
|
||||
+ if ((~eventFlags & eventFlags_) == eventFlags_)
|
||||
+ return;
|
||||
+
|
||||
+ short newFlags = ~eventFlags & eventFlags_;
|
||||
+
|
||||
+ eventFlags_ = 0;
|
||||
+ if (event_del(&event_) == -1) {
|
||||
+ GlobalOutput("TConnection::setFlags event_del");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ setFlags(newFlags);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* Closes a connection
|
||||
*/
|
||||
void TNonblockingServer::TConnection::close() {
|
||||
+ // Close the socket
|
||||
+ tSocket_->close();
|
||||
+
|
||||
+ // close any factory produced transports
|
||||
+ factoryInputTransport_->close();
|
||||
+ factoryOutputTransport_->close();
|
||||
+
|
||||
+ // Give this object back to the server that owns it
|
||||
+ processor_.reset();
|
||||
+
|
||||
+ // Remove all queued write requests
|
||||
+ while(writeRequests_.empty() == false)
|
||||
+ writeRequests_.pop();
|
||||
+
|
||||
+ // Reset write buffer position to the beginning of the buffer.
|
||||
+ outputTransport_->resetBuffer();
|
||||
+ externalTransport_->resetBuffer();
|
||||
+
|
||||
// Delete the registered libevent
|
||||
if (event_del(&event_) == -1) {
|
||||
GlobalOutput.perror("TConnection::close() event_del", errno);
|
||||
@@ -831,16 +986,9 @@
|
||||
if (serverEventHandler_ != NULL) {
|
||||
serverEventHandler_->deleteContext(connectionContext_, inputProtocol_, outputProtocol_);
|
||||
}
|
||||
- ioThread_ = NULL;
|
||||
-
|
||||
- // Close the socket
|
||||
- tSocket_->close();
|
||||
|
||||
- // close any factory produced transports
|
||||
- factoryInputTransport_->close();
|
||||
- factoryOutputTransport_->close();
|
||||
+ ioThread_ = NULL;
|
||||
|
||||
- // Give this object back to the server that owns it
|
||||
server_->returnConnection(this);
|
||||
}
|
||||
|
||||
@@ -856,6 +1004,7 @@
|
||||
if (writeLimit > 0 && largestWriteBufferSize_ > writeLimit) {
|
||||
// just start over
|
||||
outputTransport_->resetBuffer(server_->getWriteBufferDefaultSize());
|
||||
+ externalTransport_->resetBuffer(server_->getWriteBufferDefaultSize());
|
||||
largestWriteBufferSize_ = 0;
|
||||
}
|
||||
}
|
||||
@@ -1122,7 +1271,7 @@
|
||||
void TNonblockingServer::setThreadManager(boost::shared_ptr<ThreadManager> threadManager) {
|
||||
threadManager_ = threadManager;
|
||||
if (threadManager != NULL) {
|
||||
- threadManager->setExpireCallback(std::tr1::bind(&TNonblockingServer::expireClose, this, std::tr1::placeholders::_1));
|
||||
+ threadManager->setExpireCallback(boost::bind(&TNonblockingServer::expireClose, this, _1));
|
||||
threadPoolProcessing_ = true;
|
||||
} else {
|
||||
threadPoolProcessing_ = false;
|
||||
Index: thrift-0.9.0/lib/cpp/src/thrift/transport/TBufferTransports.cpp
|
||||
===================================================================
|
||||
--- thrift-0.9.0.orig/lib/cpp/src/thrift/transport/TBufferTransports.cpp 2012-10-12 02:58:06.000000000 +0200
|
||||
+++ thrift-0.9.0/lib/cpp/src/thrift/transport/TBufferTransports.cpp 2013-08-15 16:53:40.000000000 +0200
|
||||
@@ -374,6 +374,14 @@
|
||||
wBase_ += len;
|
||||
}
|
||||
|
||||
+void TMemoryBuffer::revertLastWrite(uint32_t len)
|
||||
+{
|
||||
+ if (wBase_ - len < rBase_)
|
||||
+ throw TTransportException("Can't reset write pointer before read pointer");
|
||||
+
|
||||
+ wBase_ -= len;
|
||||
+}
|
||||
+
|
||||
const uint8_t* TMemoryBuffer::borrowSlow(uint8_t* buf, uint32_t* len) {
|
||||
(void) buf;
|
||||
rBound_ = wBase_;
|
||||
Index: thrift-0.9.0/lib/cpp/src/thrift/transport/TBufferTransports.h
|
||||
===================================================================
|
||||
--- thrift-0.9.0.orig/lib/cpp/src/thrift/transport/TBufferTransports.h 2012-10-12 02:58:06.000000000 +0200
|
||||
+++ thrift-0.9.0/lib/cpp/src/thrift/transport/TBufferTransports.h 2013-08-15 16:53:40.000000000 +0200
|
||||
@@ -683,6 +683,9 @@
|
||||
// that had been provided by getWritePtr().
|
||||
void wroteBytes(uint32_t len);
|
||||
|
||||
+ // Resets the write pointer by len bytes if the were not yet read.
|
||||
+ void revertLastWrite(uint32_t len);
|
||||
+
|
||||
/*
|
||||
* TVirtualTransport provides a default implementation of readAll().
|
||||
* We want to use the TBufferBase version instead.
|
||||
Index: thrift-0.9.0/lib/cpp/src/thrift/transport/TLibEventTransport.h
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ thrift-0.9.0/lib/cpp/src/thrift/transport/TLibEventTransport.h 2013-08-15 16:53:40.000000000 +0200
|
||||
@@ -0,0 +1,114 @@
|
||||
+#ifndef _THRIFT_TRANSPORT_TLIB_EVENTTRANSPORT_H_
|
||||
+#define _THRIFT_TRANSPORT_TLIB_EVENTTRANSPORT_H_ 1
|
||||
+
|
||||
+#include "TSocket.h"
|
||||
+#include "TBufferTransports.h"
|
||||
+
|
||||
+#include <boost/function.hpp>
|
||||
+#include <boost/shared_ptr.hpp>
|
||||
+
|
||||
+struct event_base;
|
||||
+
|
||||
+namespace apache { namespace thrift {
|
||||
+namespace protocol {
|
||||
+ class TProtocol;
|
||||
+}
|
||||
+namespace transport {
|
||||
+
|
||||
+/**
|
||||
+ * TLibEventTransport is used by TNonblockingServer to integrate events from
|
||||
+ * an external libevent source.
|
||||
+ *
|
||||
+ * To support asynchronous communication between a thrift client and server the
|
||||
+ * following pattern is required:
|
||||
+ * - all request in a Thrift service must be defined as oneway
|
||||
+ * - an additional "callback" service is required to send asynchronous
|
||||
+ * responses and updates from server to client. The "callback" service is
|
||||
+ * implemented by the client. Here as well all request have to be oneway.
|
||||
+ * Since all request are oneway they can share the same thrift connection.
|
||||
+ * - In the server the callback client object must be initialized in the
|
||||
+ * handler factory with the protocol from TConnectionInfo. For
|
||||
+ * TLibEventTransport one has to use TLibEventTransport::getProtocol().
|
||||
+ * - In the client one has to create an own thread to handle the callbacks.
|
||||
+ * One only has to call process of the generated "callback" processor with
|
||||
+ * the protocols created for the server connection.
|
||||
+ *
|
||||
+ * For an external event beginWriteEvent() must be called before using the
|
||||
+ * the callback object to write 4 bytes for the frame size into the output
|
||||
+ * transport. After using the callback object endWriteEvent() must be called
|
||||
+ * to calculate and set the frame size and notify libevent for writting.
|
||||
+ */
|
||||
+class TLibEventTransport : public TSocket
|
||||
+{
|
||||
+public:
|
||||
+ typedef boost::function<void ()> WriteEventCb;
|
||||
+
|
||||
+ /*!
|
||||
+ * TLibEventTransport is created by TNonblockingServer when a new client
|
||||
+ * connection is accepted.
|
||||
+ *
|
||||
+ * @param protocol protocol for the callback object
|
||||
+ * @param beginEventCb callback to start sending an asynchronous event
|
||||
+ * @param endEventCb callback to finish sending an asynchronous event
|
||||
+ */
|
||||
+ TLibEventTransport(boost::shared_ptr<protocol::TProtocol>& protocol,
|
||||
+ WriteEventCb beginEventCb,
|
||||
+ WriteEventCb endEventCb) :
|
||||
+ eventBase_(0),
|
||||
+ protocol_(protocol),
|
||||
+ beginWriteEventCb_(beginEventCb),
|
||||
+ endWriteEventCb_(endEventCb) {}
|
||||
+
|
||||
+ /**
|
||||
+ * @returns event_base used by this transport.
|
||||
+ */
|
||||
+ event_base& getEventBase() const {
|
||||
+ assert(eventBase_);
|
||||
+ return *eventBase_;
|
||||
+ }
|
||||
+
|
||||
+ /*!
|
||||
+ * Setting correct event_base from TNonblockingServer.
|
||||
+ *
|
||||
+ * @param ev event_base used by TNonblockingServer
|
||||
+ */
|
||||
+ void setEventBase(event_base& ev) {
|
||||
+ eventBase_ = &ev;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @returns the protocol for the callback object.
|
||||
+ */
|
||||
+ boost::shared_ptr<protocol::TProtocol>& getProtocol() {
|
||||
+ return protocol_;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Writes 4 bytes for the frame header into the output transport.
|
||||
+ *
|
||||
+ * Must be called before using a request from the callback object.
|
||||
+ */
|
||||
+ void beginWriteEvent() {
|
||||
+ beginWriteEventCb_();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Calculates the frame size and notifies libevent for writting.
|
||||
+ *
|
||||
+ * Must be called after using a request from the callback object.
|
||||
+ */
|
||||
+ void endWriteEvent() {
|
||||
+ endWriteEventCb_();
|
||||
+ }
|
||||
+
|
||||
+private:
|
||||
+ event_base* eventBase_;
|
||||
+ boost::shared_ptr<protocol::TProtocol> protocol_;
|
||||
+ WriteEventCb beginWriteEventCb_;
|
||||
+ WriteEventCb endWriteEventCb_;
|
||||
+};
|
||||
+
|
||||
+}}} // apache::thrift::transport
|
||||
+
|
||||
+
|
||||
+#endif // _THRIFT_TRANSPORT_TLIB_EVENTTRANSPORT_H_
|
22
0003-TDenseProtocol.patch
Normal file
22
0003-TDenseProtocol.patch
Normal file
@ -0,0 +1,22 @@
|
||||
Index: thrift-0.9.0/lib/cpp/src/thrift/protocol/TDenseProtocol.cpp
|
||||
===================================================================
|
||||
--- thrift-0.9.0.orig/lib/cpp/src/thrift/protocol/TDenseProtocol.cpp
|
||||
+++ thrift-0.9.0/lib/cpp/src/thrift/protocol/TDenseProtocol.cpp
|
||||
@@ -304,7 +304,7 @@ uint32_t TDenseProtocol::writeStructBegi
|
||||
|
||||
// We need a new field index for this structure.
|
||||
idx_stack_.push_back(0);
|
||||
- return 0;
|
||||
+ return xfer;
|
||||
}
|
||||
|
||||
uint32_t TDenseProtocol::writeStructEnd() {
|
||||
@@ -538,7 +538,7 @@ uint32_t TDenseProtocol::readStructBegin
|
||||
|
||||
// We need a new field index for this structure.
|
||||
idx_stack_.push_back(0);
|
||||
- return 0;
|
||||
+ return xfer;
|
||||
}
|
||||
|
||||
uint32_t TDenseProtocol::readStructEnd() {
|
3
thrift-0.9.0.tar.bz2
Normal file
3
thrift-0.9.0.tar.bz2
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9ef99a899b56619a51b218481e8536bbdef38116fe84f1213ae1c33e44ea602e
|
||||
size 2160871
|
106
thrift.changes
Normal file
106
thrift.changes
Normal file
@ -0,0 +1,106 @@
|
||||
-------------------------------------------------------------------
|
||||
Wed Sep 25 08:54:20 UTC 2013 - d.desai@rtsgroup.net
|
||||
|
||||
- number of bytes written to transport and number of bytes
|
||||
returned from write() method was not same. Fixed this
|
||||
problem in TDenseProtocol.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Aug 15 15:15:51 UTC 2013 - o.herrmann217@googlemail.com
|
||||
|
||||
- Extended 0002-TNonblockingServer-TLibEventTransport.patch to
|
||||
properly close TConnection when a client disconnects while
|
||||
still receiving updates from libevent.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Aug 7 12:07:33 UTC 2013 - d.desai@rtsgroup.net
|
||||
|
||||
- Fixed multiple crashes in TNonblockingServer to work with lib_event.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Jun 21 11:12:57 UTC 2013 - o.herrmann217@googlemail.com
|
||||
|
||||
- Changed 0002-TNonblockingServer-TLibEventTransport.patch to
|
||||
install new header file with automake.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Jun 20 21:12:12 UTC 2013 - o.herrmann217@googlemail.com
|
||||
|
||||
- Replaced std::tr1::bind with boost::bind in TNonblockingServer
|
||||
to fix compilation error on RHEL 5.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Jun 20 11:51:54 UTC 2013 - o.herrmann217@googlemail.com
|
||||
|
||||
- Removed BuildRequires for boost-static
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Jun 20 11:13:43 UTC 2013 - o.herrmann217@googlemail.com
|
||||
|
||||
- Created new patch for integrating external libevent clients in
|
||||
TNonblockingServer.
|
||||
- Removed 0003-TNonblokingServer-release-handler-on-close.patch.
|
||||
It is now part of 0002-TNonblockingServer-TLibEventTransport.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue May 14 07:40:45 UTC 2013 - d.desai@rtsgroup.net
|
||||
|
||||
- Reverted changes for dependency of openssl for sles_11.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue May 14 07:02:05 UTC 2013 - d.desai@rtsgroup.net
|
||||
|
||||
- Added dependency of openssl for sles_11.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon May 13 15:30:08 UTC 2013 - d.desai@rtsgroup.net
|
||||
|
||||
- Created patch 0003 to release handler on close in
|
||||
TNonblockingServer
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu May 9 12:23:02 UTC 2013 - o.herrmann217@googlemail.com
|
||||
|
||||
- Fixed reset of smart pointer in patch 0002
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu May 9 11:16:57 UTC 2013 - o.herrmann217@googlemail.com
|
||||
|
||||
- Created patch 0002 to access event_base from libevent in
|
||||
TNonblockingServer
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Jan 23 18:26:38 UTC 2013 - d.desai@rtsgroup.net
|
||||
|
||||
- Removed boost version
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Jan 23 14:51:46 UTC 2013 - o.herrmann217@googlemail.com
|
||||
|
||||
- Build with --hash-style=sysv
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Sun Dec 2 13:58:46 UTC 2012 - o.herrmann217@googlemail.com
|
||||
|
||||
- Striped one directory in patch 0001
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Sun Dec 2 13:41:57 UTC 2012 - o.herrmann217@googlemail.com
|
||||
|
||||
- Patch for missing limit headers
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Sun Dec 2 12:40:06 UTC 2012 - o.herrmann217@googlemail.com
|
||||
|
||||
- Call make with -j1 to fix compile problem temporally
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Nov 27 21:58:37 UTC 2012 - jblunck@opensuse.org
|
||||
|
||||
- Update to 0.9.0
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Jul 30 17:26:10 UTC 2010 - dmacvicar@novell.com
|
||||
|
||||
- initial package for 0.2.0
|
||||
|
171
thrift.spec
Normal file
171
thrift.spec
Normal file
@ -0,0 +1,171 @@
|
||||
|
||||
%bcond_with perl
|
||||
%bcond_with python
|
||||
|
||||
Name: thrift
|
||||
Version: 0.9.0
|
||||
Release: 0
|
||||
Group: Development/Libraries/C and C++
|
||||
License: Apache License
|
||||
Source0: %{name}-%{version}.tar.bz2
|
||||
Patch1: 0001-Add-missing-limits-header.patch
|
||||
Patch2: 0002-TNonblockingServer-TLibEventTransport.patch
|
||||
Patch3: 0003-TDenseProtocol.patch
|
||||
Summary: Framework for scalable cross-language services development in C++, Java, Python, PHP, and Ruby
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
BuildRequires: gcc-c++
|
||||
BuildRequires: boost-devel
|
||||
# we build the gem separately
|
||||
#BuildRequires: ruby-devel
|
||||
#BuildRequires: java-devel
|
||||
|
||||
#%if %{with python}
|
||||
BuildRequires: python-devel
|
||||
#%endif
|
||||
|
||||
%if %{with perl}
|
||||
BuildRequires: perl
|
||||
%endif
|
||||
|
||||
BuildRequires: bison
|
||||
BuildRequires: flex
|
||||
BuildRequires: pkg-config
|
||||
BuildRequires: openssl-devel
|
||||
BuildRequires: libevent-devel
|
||||
|
||||
%description
|
||||
Thrift is a software framework for scalable cross-language services
|
||||
development. It combines a powerful software stack with a code generation
|
||||
engine to build services that work efficiently and seamlessly between C++,
|
||||
Java, C#, Python, Ruby, Perl, PHP, Objective C/Cocoa, Smalltalk, Erlang,
|
||||
Objective Caml, and Haskell.
|
||||
|
||||
%package -n libthrift0_9_0
|
||||
Summary: Thrift shared library
|
||||
Group: System/Libraries
|
||||
%description -n libthrift0_9_0
|
||||
Thrift shared library
|
||||
|
||||
Thrift is a software framework for scalable cross-language services
|
||||
development. It combines a powerful software stack with a code generation
|
||||
engine to build services that work efficiently and seamlessly between C++,
|
||||
Java, C#, Python, Ruby, Perl, PHP, Objective C/Cocoa, Smalltalk, Erlang,
|
||||
Objective Caml, and Haskell.
|
||||
|
||||
%post -n libthrift0_9_0 -p /sbin/ldconfig
|
||||
%postun -n libthrift0_9_0 -p /sbin/ldconfig
|
||||
|
||||
%package -n libthrift-devel
|
||||
Summary: Thrift C++ library development files
|
||||
Group: Development/Libraries
|
||||
%description -n libthrift-devel
|
||||
Thrift C++ library development files
|
||||
|
||||
Thrift is a software framework for scalable cross-language services
|
||||
development. It combines a powerful software stack with a code generation
|
||||
engine to build services that work efficiently and seamlessly between C++,
|
||||
Java, C#, Python, Ruby, Perl, PHP, Objective C/Cocoa, Smalltalk, Erlang,
|
||||
Objective Caml, and Haskell.
|
||||
|
||||
%if %{with perl}
|
||||
%package -n perl-thrift
|
||||
Summary: Thrift perl library
|
||||
Group: Development/Libraries/Perl
|
||||
%description -n perl-thrift
|
||||
Thrift perl library
|
||||
|
||||
Thrift is a software framework for scalable cross-language services
|
||||
development. It combines a powerful software stack with a code generation
|
||||
engine to build services that work efficiently and seamlessly between C++,
|
||||
Java, C#, Python, Ruby, Perl, PHP, Objective C/Cocoa, Smalltalk, Erlang,
|
||||
Objective Caml, and Haskell.
|
||||
%endif
|
||||
|
||||
%if %{with python}
|
||||
%package -n python-thrift
|
||||
Summary: Thrift python library
|
||||
Group: Development/Libraries/Python
|
||||
%description -n python-thrift
|
||||
Thrift python library
|
||||
|
||||
Thrift is a software framework for scalable cross-language services
|
||||
development. It combines a powerful software stack with a code generation
|
||||
engine to build services that work efficiently and seamlessly between C++,
|
||||
Java, C#, Python, Ruby, Perl, PHP, Objective C/Cocoa, Smalltalk, Erlang,
|
||||
Objective Caml, and Haskell.
|
||||
%endif
|
||||
|
||||
%prep
|
||||
|
||||
%setup
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
|
||||
%build
|
||||
export CXXFLAGS="%{optflags} -fPIC"
|
||||
export LDFLAGS="-Wl,--hash-style=sysv"
|
||||
%{configure} --without-ruby
|
||||
make -j1
|
||||
#%{?jobs:-j%jobs}
|
||||
|
||||
%install
|
||||
pushd compiler/cpp
|
||||
%makeinstall
|
||||
popd
|
||||
pushd lib/cpp
|
||||
%makeinstall
|
||||
popd
|
||||
|
||||
%if %{with python}
|
||||
pushd lib/py
|
||||
%makeinstall
|
||||
popd
|
||||
%endif
|
||||
|
||||
%if %{with perl}
|
||||
pushd lib/perl
|
||||
perl Makefile.PL
|
||||
%perl_make_install
|
||||
%perl_process_packlist
|
||||
rm -rf %{buildroot}%{perl_vendorarch}/auto
|
||||
popd
|
||||
%endif
|
||||
|
||||
%clean
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%doc CHANGES CONTRIBUTORS DISCLAIMER LICENSE NOTICE NEWS
|
||||
%{_bindir}/thrift
|
||||
|
||||
%files -n libthrift0_9_0
|
||||
%defattr(-,root,root)
|
||||
%{_libdir}/*-0.9.0.so
|
||||
|
||||
%files -n libthrift-devel
|
||||
%defattr(-,root,root)
|
||||
#%dir %{_includedir}/thrift
|
||||
%{_includedir}/thrift
|
||||
%{_libdir}/*.a
|
||||
%{_libdir}/*.la
|
||||
%{_libdir}/*.so
|
||||
%exclude %{_libdir}/*-0.9.0.so
|
||||
%{_libdir}/pkgconfig/*.pc
|
||||
|
||||
%if %{with perl}
|
||||
%files -n perl-thrift
|
||||
%defattr(-,root,root)
|
||||
%{perl_vendorlib}/Thrift
|
||||
%{perl_vendorlib}/Thrift.pm
|
||||
/var/adm/perl-modules/thrift
|
||||
%endif
|
||||
|
||||
%if %{with python}
|
||||
%files -n python-thrift
|
||||
%defattr(-,root,root)
|
||||
%{py_sitedir}/*
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
|
Loading…
Reference in New Issue
Block a user