-- fix issues with TFileTransport

Summary:
- Make sure that buffers are always emptied when destructor is called (or when file is closed)
- make flush a no-op if file is not open
- dont allow new events to be enqueued if the file is in the process of being closed

Reviewed By: slee, jwang

Test Plan: tested with building search indices on top of thrift logs


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665094 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/transport/TFileTransport.cpp b/lib/cpp/src/transport/TFileTransport.cpp
index 4ecaa95..5fb9ef3 100644
--- a/lib/cpp/src/transport/TFileTransport.cpp
+++ b/lib/cpp/src/transport/TFileTransport.cpp
@@ -30,6 +30,7 @@
 using namespace facebook::thrift::protocol;
 
 #ifndef HAVE_CLOCK_GETTIME
+
 /**
  * Fake clock_gettime for systems like darwin
  *
@@ -185,6 +186,11 @@
 }
 
 void TFileTransport::enqueueEvent(const uint8_t* buf, uint32_t eventLen, bool blockUntilFlush) {
+  // can't enqueue more events if file is going to close
+  if (closing_) {
+    return;
+  }
+
   // make sure that event size is valid
   if ( (maxEventSize_ > 0) && (eventLen > maxEventSize_) ) {
     T_ERROR("msg size is greater than max event size: %u > %u\n", eventLen, maxEventSize_);
@@ -291,12 +297,16 @@
   while(1) {
     // this will only be true when the destructor is being invoked
     if(closing_) {
-      if(-1 == ::close(fd_)) {
-        perror("TFileTransport: error in close");
-        throw TTransportException("TFileTransport: error in file close");
+      // empty out both the buffers
+      if (enqueueBuffer_->isEmpty() && dequeueBuffer_->isEmpty()) {
+        if(-1 == ::close(fd_)) {
+          perror("TFileTransport: error in close");
+          throw TTransportException("TFileTransport: error in file close");
+        }
+        fd_ = 0;
+        pthread_exit(NULL);
+        return;
       }
-      fd_ = 0;
-      return;
     }
 
     if (swapEventBuffers(&ts_next_flush)) {
@@ -395,6 +405,10 @@
 }
 
 void TFileTransport::flush() {
+  // file must be open for writing for any flushing to take place
+  if (writerThreadId_ <= 0) {
+    return;
+  }
   // wait for flush to take place
   pthread_mutex_lock(&mutex_);