From 9dc907fd61dddd46eaf5ada4ea9542c1b2c875ff57042c02c9696c47519fc738 Mon Sep 17 00:00:00 2001 From: Martin Pluskal Date: Tue, 3 Mar 2015 22:11:19 +0000 Subject: [PATCH] Accepting request 288551 from home:pluskalm:branches:devel:tools - Disable building of static library - Do not manually set LDFLAGS - Remove obsolete patches * 0001-Add-missing-limits-header.patch * 0002-TNonblockingServer-TLibEventTransport.patch * 0003-TDenseProtocol.patch - Update library name to match shlib naming policy - Update to 0.9.2 * numerous changes, see provide CHANGES for details OBS-URL: https://build.opensuse.org/request/show/288551 OBS-URL: https://build.opensuse.org/package/show/devel:tools/thrift?expand=0&rev=6 --- 0001-Add-missing-limits-header.patch | 36 - ...NonblockingServer-TLibEventTransport.patch | 967 ------------------ 0003-TDenseProtocol.patch | 22 - thrift-0.9.1.tar.gz | 3 - thrift-0.9.2.tar.gz | 3 + thrift-0.9.2.tar.gz.asc | 7 + thrift.changes | 17 + thrift.keyring | 40 + thrift.spec | 77 +- 9 files changed, 106 insertions(+), 1066 deletions(-) delete mode 100644 0001-Add-missing-limits-header.patch delete mode 100644 0002-TNonblockingServer-TLibEventTransport.patch delete mode 100644 0003-TDenseProtocol.patch delete mode 100644 thrift-0.9.1.tar.gz create mode 100644 thrift-0.9.2.tar.gz create mode 100644 thrift-0.9.2.tar.gz.asc create mode 100644 thrift.keyring diff --git a/0001-Add-missing-limits-header.patch b/0001-Add-missing-limits-header.patch deleted file mode 100644 index 6d0582c..0000000 --- a/0001-Add-missing-limits-header.patch +++ /dev/null @@ -1,36 +0,0 @@ -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 - #include - #include -+#include - #include - #include - -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 -+#include - #include - #include - -Index: thrift-0.9.1/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp -=================================================================== ---- thrift-0.9.1.orig/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp 2012-12-02 07:53:04.218514119 -0600 -+++ thrift-0.9.1/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp 2012-12-02 07:54:24.122510554 -0600 -@@ -20,6 +20,7 @@ - #include - - #include -+#include - #include - #include - #include diff --git a/0002-TNonblockingServer-TLibEventTransport.patch b/0002-TNonblockingServer-TLibEventTransport.patch deleted file mode 100644 index 45e60ac..0000000 --- a/0002-TNonblockingServer-TLibEventTransport.patch +++ /dev/null @@ -1,967 +0,0 @@ -Index: thrift-0.9.1/lib/cpp/Makefile.am -=================================================================== ---- thrift-0.9.1.orig/lib/cpp/Makefile.am 2012-10-12 02:58:06.000000000 +0200 -+++ thrift-0.9.1/lib/cpp/Makefile.am 2013-08-15 16:53:40.000000000 +0200 -@@ -191,7 +191,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.1/lib/cpp/Makefile.in -=================================================================== ---- thrift-0.9.1.orig/lib/cpp/Makefile.in 2012-10-12 02:59:49.000000000 +0200 -+++ thrift-0.9.1/lib/cpp/Makefile.in 2013-08-15 16:53:40.000000000 +0200 -@@ -627,7 +627,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.1/lib/cpp/src/thrift/server/TNonblockingServer.cpp -=================================================================== ---- thrift-0.9.1.orig/lib/cpp/src/thrift/server/TNonblockingServer.cpp 2012-10-12 02:58:06.000000000 +0200 -+++ thrift-0.9.1/lib/cpp/src/thrift/server/TNonblockingServer.cpp 2013-08-15 17:11:07.000000000 +0200 -@@ -23,11 +23,14 @@ - - #include - #include --#include -+#include - #include - #include - -+#include -+ - #include -+#include - - #ifdef HAVE_SYS_SOCKET_H - #include -@@ -75,13 +78,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 -@@ -92,7 +88,6 @@ - */ - enum TAppState { - APP_INIT, -- APP_READ_FRAME_SIZE, - APP_READ_REQUEST, - APP_WAIT_TASK, - APP_SEND_RESULT, -@@ -115,7 +110,7 @@ - boost::shared_ptr processor_; - - /// Object wrapping network socket -- boost::shared_ptr tSocket_; -+ boost::shared_ptr tSocket_; - - /// Libevent object - struct event event_; -@@ -123,8 +118,8 @@ - /// Libevent flags - short eventFlags_; - -- /// Socket mode -- TSocketState socketState_; -+ /// Tells whether the frame size was read completely. -+ bool readFrameSize_; - - /// Application state - TAppState appState_; -@@ -141,15 +136,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_; - -@@ -168,6 +160,9 @@ - /// Transport that processor writes to - boost::shared_ptr outputTransport_; - -+ /// Transport that processes writes from an external libevent source. -+ boost::shared_ptr externalTransport_; -+ - /// extra transport generated by transport factory (e.g. BufferedRouterTransport) - boost::shared_ptr factoryInputTransport_; - boost::shared_ptr factoryOutputTransport_; -@@ -184,6 +179,16 @@ - /// Thrift call context, if any - void *connectionContext_; - -+ /// Node for queuing write requests from internal and external sources. -+ typedef std::pair WriteRequest; -+ -+ /// Queue with write requests from outputTransport_ and externalTransport_. -+ std::queue 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); -@@ -194,6 +199,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); -@@ -207,12 +217,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); - - public: - -@@ -232,7 +267,16 @@ - inputTransport_.reset(new TMemoryBuffer(readBuffer_, readBufferSize_)); - outputTransport_.reset( - new TMemoryBuffer(static_cast(server_->getWriteBufferDefaultSize()))); -- tSocket_.reset(new TSocket()); -+ externalTransport_.reset( -+ new TMemoryBuffer(static_cast(server_->getWriteBufferDefaultSize()))); -+ -+ boost::shared_ptr 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); - } - -@@ -243,6 +287,18 @@ - /// Close this connection and free or reset its resources. - void close(); - -+ /** -+ * 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. - * -@@ -266,13 +322,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); - } - - /** -@@ -393,6 +449,7 @@ - socklen_t addrLen) { - tSocket_->setSocketFD(socket); - tSocket_->setCachedAddress(addr, addrLen); -+ tSocket_->setEventBase(*(ioThread->getEventBase())); - - ioThread_ = ioThread; - server_ = ioThread->getServer(); -@@ -402,12 +459,9 @@ - readBufferPos_ = 0; - readWant_ = 0; - -- writeBuffer_ = NULL; -- writeBufferSize_ = 0; -- writeBufferPos_ = 0; - largestWriteBufferSize_ = 0; - -- socketState_ = SOCKET_RECV_FRAMING; -+ readFrameSize_ = true; - callsForResize_ = 0; - - // get input/transports -@@ -435,12 +489,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; -@@ -456,20 +527,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 @@ - (uint64_t)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); - -@@ -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", THRIFT_GET_SOCKET_ERROR); -@@ -831,16 +986,9 @@ - if (serverEventHandler_) { - 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(static_cast(server_->getWriteBufferDefaultSize())); -+ externalTransport_->resetBuffer(static_cast(server_->getWriteBufferDefaultSize())); - largestWriteBufferSize_ = 0; - } - } -@@ -1131,7 +1280,7 @@ - void TNonblockingServer::setThreadManager(boost::shared_ptr threadManager) { - threadManager_ = threadManager; - if (threadManager) { -- threadManager->setExpireCallback(apache::thrift::stdcxx::bind(&TNonblockingServer::expireClose, this, apache::thrift::stdcxx::placeholders::_1)); -+ threadManager->setExpireCallback(boost::bind(&TNonblockingServer::expireClose, this, _1)); - threadPoolProcessing_ = true; - } else { - threadPoolProcessing_ = false; -Index: thrift-0.9.1/lib/cpp/src/thrift/transport/TBufferTransports.cpp -=================================================================== ---- thrift-0.9.1.orig/lib/cpp/src/thrift/transport/TBufferTransports.cpp 2012-10-12 02:58:06.000000000 +0200 -+++ thrift-0.9.1/lib/cpp/src/thrift/transport/TBufferTransports.cpp 2013-08-15 16:53:40.000000000 +0200 -@@ -378,6 +378,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 -+#include -+ -+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 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, -+ 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& 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_; -+ WriteEventCb beginWriteEventCb_; -+ WriteEventCb endWriteEventCb_; -+}; -+ -+}}} // apache::thrift::transport -+ -+ -+#endif // _THRIFT_TRANSPORT_TLIB_EVENTTRANSPORT_H_ diff --git a/0003-TDenseProtocol.patch b/0003-TDenseProtocol.patch deleted file mode 100644 index 481e945..0000000 --- a/0003-TDenseProtocol.patch +++ /dev/null @@ -1,22 +0,0 @@ -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() { diff --git a/thrift-0.9.1.tar.gz b/thrift-0.9.1.tar.gz deleted file mode 100644 index 73f8f0e..0000000 --- a/thrift-0.9.1.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ac175080c8cac567b0331e394f23ac306472c071628396db2850cb00c41b0017 -size 3402353 diff --git a/thrift-0.9.2.tar.gz b/thrift-0.9.2.tar.gz new file mode 100644 index 0000000..2e0536b --- /dev/null +++ b/thrift-0.9.2.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cef50d3934c41db5fa7724440cc6f10a732e7a77fe979b98c23ce45725349570 +size 8053046 diff --git a/thrift-0.9.2.tar.gz.asc b/thrift-0.9.2.tar.gz.asc new file mode 100644 index 0000000..fcf0ae0 --- /dev/null +++ b/thrift-0.9.2.tar.gz.asc @@ -0,0 +1,7 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1 + +iF4EABEIAAYFAlRZonEACgkQuwY2j2a3ePljGQD/SwxjjsWUFADajiK2VQxTugfl +0GLPrC0LugahRChg77ABAJVI4mgI1lkKVXajYNLYln29oUhPa+Zq0avZo8oPyxWd +=JvzH +-----END PGP SIGNATURE----- diff --git a/thrift.changes b/thrift.changes index 6bb3c6e..4e57bb2 100644 --- a/thrift.changes +++ b/thrift.changes @@ -1,3 +1,20 @@ +------------------------------------------------------------------- +Mon Mar 2 18:44:32 UTC 2015 - mpluskal@suse.com + +- Disable building of static library +- Do not manually set LDFLAGS + +------------------------------------------------------------------- +Mon Mar 2 14:23:16 UTC 2015 - mpluskal@suse.com + +- Remove obsolete patches + * 0001-Add-missing-limits-header.patch + * 0002-TNonblockingServer-TLibEventTransport.patch + * 0003-TDenseProtocol.patch +- Update library name to match shlib naming policy +- Update to 0.9.2 + * numerous changes, see provide CHANGES for details + ------------------------------------------------------------------- Sat Feb 22 20:05:26 UTC 2014 - opensuse@dstoecker.de diff --git a/thrift.keyring b/thrift.keyring new file mode 100644 index 0000000..b454bde --- /dev/null +++ b/thrift.keyring @@ -0,0 +1,40 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2 + +mQMuBE2mAQ8RCACgm0DOTToYRWzbuOqxAxDpviHEa3OKhX8H7TaOscwicXiaszkC +yEfvap5j3VaD8g3zYsKoBShtmyR3ceN5/kjA+XYJYGtkvR7V4oq5PJRc/2Z4KEf4 +uBND9FDBwg+evZWbax0914v21DRCVsSYWKVL4+Fh0Gt7MMjSONr1dvA7p+buMdPK +LdeUY7G1J0fUwL2QoSnlcyQ7adSyaDSfRZpDXCQvuCVF6CotikEsUdS1eoGtJll0 +cc4cTpENVguiMAP3IN++756Jt2DZ7ogGzuZQhzz2K8Hpff4X/NkjkpIEexPjG1So +iQLT+xYpIS3IXUqtSWP/ns0viI83S6EERWWnAQC2YIjyLIGxkPSHeQiXjdnY3Fwy +na435DpYvmdMXxcrbQgAhLfqLRkvu19nj41WHfiWbmMTfqzDeQqUusE1rjN5OS3j +MbcuNFWIIQ8C+7JYe4kQiUfYiraTmQmz3YCR8r2iUViVZHhypEagzHM1jV2TE/p9 +XE6jDPHsxs8/80uuzweVTtFtF9jmNqkoXTGFQjMCcBFVx8nNvrWnRgTuiTDLJzfn +pjpipFKuGQHZ8237cDMfmgkteddpN/HArgPBknUg43gGiIi1EL2chH2mHFDrFdpe +KtbhOVk9xCHA00JVPpoQ2lryWMmDD08PY8e1/8UC0yRsDsiFXUh26WGLKZU0Mz8Q +g6urPlJxbn+cLAqf/g1wrR9B/nuoB/zbD1dh2C1thwf/RaMJXbnGoCha6LGXh7Nx +B85uVvlCW4vx1R23BbzdRu28c7IHObtUVICZLtgeekXYzupzkctGO8tM5FXH8G8J +b7CeMfUWKitz2qTlf+Kb5VxtVenEn6ZSAZS8oOmD4Hyjoe8atVZpXB1yhbq353vp +9Jx0ovYs9V+KeBU0qu1gYKovK/QUBkjCeTyyfqu7qbZ1sDPVduHNHL+MyGelcDVg +ar8t67kdAlYxZ7DE1Pr8PlIbkWQafM+zEd2kvQGbpIqbIPuJv7MFRRO+jdKn6EqQ +5u/eL4hkgDABf4p+pP8Di3o4pLOiFrsiFZ/QIYf0G95O8k3MdMpX3Spc9Xnx5rsk +B7QiSmFrZSBGYXJyZWxsIDxqZmFycmVsbEBhcGFjaGUub3JnPohGBBARAgAGBQJO +RCETAAoJENUYeCmaeyOYajEAoKmuYqHYkm3m0KvhxjAYVthbFuVnAKCEhtqXhfi2 +L85c9SsiQm3DfSOzhoh6BBMRCAAiBQJNpgEPAhsDBgsJCAcDAgYVCAIJCgsEFgID +AQIeAQIXgAAKCRC7BjaPZrd4+bXkAP9++Sa/CXEOQ4BI/KCwTi0UI3vTDDWI6LmU +oGcR+D8MnwEAtLZlu4kwyJDXKFMeo1B9tyUsR9Z9uEEruL9MHZ7Jvmi5Ag0ETaYB +DxAIAKeznjLErDjImOJLFOrde8ycskDsI0VSe8W6ObZ/4QdZOrN4GSSTsml9oRRE +ibL5PvJtCtCKn/anN7dmgCkcshVLXt0kzCDnotRP9T0J3aAgl+O5sZA9IhIDMo/f +vsTImaXx8cUzZZvg4pyUi5cdmfmwpqSBok6es4V1GnkCajVWBZ0QnWxtlIVqn6RW +bYdM32Nud4/WK5EH+N8m7+nfrN2RPYZ/IBeB0327Eq/5ZztBu1Nv2aNjw5nGkj1j +pXSOfWAc1cQAyOS1UIn7q5HZMf0BHU3yuvSKfGuDftblH/6mN4JbxgKkThiYMbr0 +Lw3w9cGdv8Wogam1QIpcP/c4qr8AAwcH/R5eRwBdizI41wT0mO6h5oY+fW1XApR2 ++kX6LJEsSQy4xLOP0UofPxOFCkHAr7tKIwUVmxXaG3R3rt2D0hfl6XsEn6wpV52o +YYMes9QGHnAZY0XnuzCWzW4m4+GUtUw5iQV0s+MZt7NocOgfia6ticMx9+7EsiOb +GEHYrd0H9bLVQAJz6j0uVSS3ggVE9l6pG2KR1aU3/LO6dUoowiR4dIGppQOGUNmi +NE27Btkm+y0GfjRRRnaOugpmrjEz4Ynomw2yclhv36HkCM9dWD7F8UzwHY1Ok2AH +6PDLJo3bFq1lFx1/4IHMiAVR7udlTmZO+enuW3QDVYDIVJdKcNbp3GuIYQQYEQgA +CQUCTaYBDwIbDAAKCRC7BjaPZrd4+bnAAPwKaGBc2yrIDdxu9KYWuEPDLYTVkFz6 +/TFHMtLz7zbyRAEAmlxId/Q7q4vYoVg1GXyWtMaVRXblIJmign/QfUX/XIg= +=SxJl +-----END PGP PUBLIC KEY BLOCK----- diff --git a/thrift.spec b/thrift.spec index c7e213d..7645019 100644 --- a/thrift.spec +++ b/thrift.spec @@ -20,8 +20,8 @@ %define _with_c 1 %define _with_perl 1 %define _with_python 1 -#%#define _with_java 1 -#%#define _with_ruby 1 +#%%define _with_java 0 +#%%define _with_ruby 0 %define _with_qt 1 %bcond_with perl @@ -32,15 +32,14 @@ %bcond_with qt Name: thrift -Version: 0.9.1 +Version: 0.9.2 Release: 0 -%define libversion 0_9_1 +%define libversion 0_9_2 %define libname %{version} -Url: http://thrift.apache.org/ -Source: http://apache.openmirror.de/thrift/0.9.1/%{name}-%{version}.tar.gz -Patch1: 0001-Add-missing-limits-header.patch -#Patch2: 0002-TNonblockingServer-TLibEventTransport.patch -#Patch3: 0003-TDenseProtocol.patch +Url: https://thrift.apache.org +Source0: https://www.apache.org/dist/thrift/%{version}/%{name}-%{version}.tar.gz +Source1: https://www.apache.org/dist/thrift/%{version}/%{name}-%{version}.tar.gz.asc +Source2: %{name}.keyring Summary: Framework for scalable cross-language services development License: Apache-2.0 Group: Development/Libraries/C and C++ @@ -63,21 +62,25 @@ BuildRequires: glib2-devel %if %{with java} BuildRequires: java-devel +BuildRequires: ant %endif %if %{with ruby} BuildRequires: ruby-devel +BuildRequires: rubygem(bundler) %endif %if %{with perl} BuildRequires: perl BuildRequires: perl(Bit::Vector) +BuildRequires: perl(Class::Accessor) %endif BuildRequires: bison BuildRequires: flex BuildRequires: libevent-devel BuildRequires: openssl-devel +BuildRequires: automake BuildRequires: pkg-config %description @@ -87,11 +90,11 @@ 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 libthrift%{libversion} +%package -n libthrift-%{libversion} Summary: Thrift shared library Group: System/Libraries -%description -n libthrift%{libversion} +%description -n libthrift-%{libversion} Thrift shared library Thrift is a software framework for scalable cross-language services @@ -100,12 +103,13 @@ 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 libthrift%{libversion} -p /sbin/ldconfig -%postun -n libthrift%{libversion} -p /sbin/ldconfig +%post -n libthrift-%{libversion} -p /sbin/ldconfig +%postun -n libthrift-%{libversion} -p /sbin/ldconfig %package -n libthrift-devel Summary: Thrift C++ library development files Group: Development/Libraries +Requires: libthrift-%{libversion} = %{version} %description -n libthrift-devel Thrift C++ library development files @@ -120,6 +124,7 @@ Objective Caml, and Haskell. %package -n perl-thrift Summary: Thrift perl library Group: Development/Libraries/Perl +%{perl_requires} %description -n perl-thrift Thrift perl library @@ -149,33 +154,28 @@ Objective Caml, and Haskell. %prep %setup -%patch1 -p1 -#%patch2 -p1 -#%patch3 -p1 %build export CXXFLAGS="%{optflags} -fPIC" -export LDFLAGS="-Wl,--hash-style=sysv" -%{configure} -# ln -s fixes 0.9.1 build, should not be requires later -ln -s . test/cpp/.libs -make -j1 + +# tests require static boost library +%configure \ + --disable-tests \ + --enable-static=no %install pushd compiler/cpp -%makeinstall +%make_install popd pushd lib/cpp -%makeinstall +%make_install popd %if %{with python} pushd lib/py -#%#makeinstall python setup.py install --prefix=%{_prefix} --root=%{buildroot} %fdupes %{buildroot}%{python_sitearch} popd -%fdupes %endif %if %{with perl} @@ -183,43 +183,44 @@ pushd lib/perl perl Makefile.PL %perl_make_install %perl_process_packlist -rm -rf %{buildroot}%{perl_vendorarch}/auto popd %endif -%clean +rm %{buildroot}%{_libdir}/*.la %files %defattr(-,root,root) -%doc CHANGES LICENSE NOTICE README +%doc CHANGES LICENSE NOTICE %{_bindir}/thrift -%files -n libthrift%{libversion} +%files -n libthrift-%{libversion} %defattr(-,root,root) -%{_libdir}/*-%{libname}.so +%{_libdir}/libthrift-*.so +%{_libdir}/libthriftnb-*.so +%{_libdir}/libthriftqt-*.so +%{_libdir}/libthriftz-*.so %files -n libthrift-devel %defattr(-,root,root) %{_includedir}/thrift -%{_libdir}/*.a -%{_libdir}/*.la -%{_libdir}/*.so -%exclude %{_libdir}/*-%{libname}.so +%{_libdir}/libthrift.so +%{_libdir}/libthriftnb.so +%{_libdir}/libthriftqt.so +%{_libdir}/libthriftz.so %{_libdir}/pkgconfig/*.pc %if %{with perl} %files -n perl-thrift %defattr(-,root,root) -%{perl_vendorlib}/Thrift %{perl_vendorlib}/Thrift.pm +%{perl_vendorlib}/Thrift %endif %if %{with python} %files -n python-thrift %defattr(-,root,root) -#%#{py_sitedir}/* -%{python_sitearch}/thrift-%{version}-py%{py_ver}.egg-info -%{python_sitearch}/thrift +%{py_sitedir}/* +%{python_sitearch}/* %endif %changelog