upstream revision 3887 released 2014-03-25

Also known as 2014 C++ Update 1 and WorkbenchUpdate20140325rev3887.
diff --git a/aos/externals/WPILib/WPILib.a b/aos/externals/WPILib/WPILib.a
index 57584f3..e0261cc 100644
--- a/aos/externals/WPILib/WPILib.a
+++ b/aos/externals/WPILib/WPILib.a
Binary files differ
diff --git a/aos/externals/WPILib/WPILib/DriverStation.cpp b/aos/externals/WPILib/WPILib/DriverStation.cpp
index 676ce77..134fe98 100644
--- a/aos/externals/WPILib/WPILib/DriverStation.cpp
+++ b/aos/externals/WPILib/WPILib/DriverStation.cpp
@@ -162,11 +162,11 @@
 	getCommonControlData(m_controlData, WAIT_FOREVER);
 	if (!lastEnabled && IsEnabled()) 
 	{
-		// If starting teleop, assume that autonomous just took up 15 seconds
+		// If starting teleop, assume that autonomous just took up 10 seconds
 		if (IsAutonomous())
 			m_approxMatchTimeOffset = Timer::GetFPGATimestamp();
 		else
-			m_approxMatchTimeOffset = Timer::GetFPGATimestamp() - 15.0;
+			m_approxMatchTimeOffset = Timer::GetFPGATimestamp() - 10.0;
 	}
 	else if (lastEnabled && !IsEnabled())
 	{
diff --git a/aos/externals/WPILib/WPILib/RobotBase.cpp b/aos/externals/WPILib/WPILib/RobotBase.cpp
index a9ec2ee..9127fb9 100644
--- a/aos/externals/WPILib/WPILib/RobotBase.cpp
+++ b/aos/externals/WPILib/WPILib/RobotBase.cpp
@@ -19,7 +19,7 @@
 RobotBase* RobotBase::m_instance = NULL;
 
 const char *FILE_NAME = "/c/FRC_Lib_Version.ini";
-const char *VERSION_STRING = "C++ 2014 Update 0";
+const char *VERSION_STRING = "C++ 2014 Update 1";
 
 
 void RobotBase::setInstance(RobotBase* robot)
diff --git a/aos/externals/WPILib/WPILib/Scripts/CopyWPILibToUpdateDirectory.cmd b/aos/externals/WPILib/WPILib/Scripts/CopyWPILibToUpdateDirectory.cmd
index 2445cce..26ecc83 100644
--- a/aos/externals/WPILib/WPILib/Scripts/CopyWPILibToUpdateDirectory.cmd
+++ b/aos/externals/WPILib/WPILib/Scripts/CopyWPILibToUpdateDirectory.cmd
@@ -6,7 +6,7 @@
 mkdir vxworks-6.3\target\h\WPILib\CAN
 mkdir vxworks-6.3\target\h\WPILib\ChipObject
 mkdir vxworks-6.3\target\h\WPILib\ChipObject\fpgainterfacecapi
-mkdir vxworks-6.3\target\h\WPILib\CInterfaces
+mkdir vxworks-6.3\target\h\WPILib\Interfaces
 mkdir vxworks-6.3\target\h\WPILib\Commands
 mkdir vxworks-6.3\target\h\WPILib\NetworkCommunication
 mkdir vxworks-6.3\target\h\WPILib\SmartDashboard
@@ -32,7 +32,7 @@
 del vxworks-6.3\target\h\WPIlib\Buttons\*.h
 del vxworks-6.3\target\h\WPIlib\CAN\*.h
 del vxworks-6.3\target\h\WPIlib\ChipObject\*.h
-del vxworks-6.3\target\h\WPIlib\CInterfaces\*.h
+del vxworks-6.3\target\h\WPIlib\Interfaces\*.h
 del vxworks-6.3\target\h\WPIlib\Commands\*.h
 del vxworks-6.3\target\h\WPIlib\NetworkCommunication\*.h
 del vxworks-6.3\target\h\WPIlib\SmartDashboard\*.h
@@ -61,7 +61,7 @@
 copy C:\WindRiver\workspace\WPILib\CAN\*.h vxworks-6.3\target\h\WPILib\CAN
 copy C:\WindRiver\workspace\WPILib\ChipObject\*.h vxworks-6.3\target\h\WPILib\ChipObject
 copy C:\WindRiver\workspace\WPILib\ChipObject\fpgainterfacecapi\*.h vxworks-6.3\target\h\WPILib\ChipObject\fpgainterfacecapi
-copy C:\WindRiver\workspace\WPILib\CInterfaces\*.h vxworks-6.3\target\h\WPILib\CInterfaces
+copy C:\WindRiver\workspace\WPILib\Interfaces\*.h vxworks-6.3\target\h\WPILib\Interfaces
 copy C:\WindRiver\workspace\WPILib\Commands\*.h vxworks-6.3\target\h\WPILib\Commands
 copy C:\WindRiver\workspace\WPILib\NetworkCommunication\*.h vxworks-6.3\target\h\WPILib\NetworkCommunication
 copy C:\WindRiver\workspace\WPILib\SmartDashboard\*.h vxworks-6.3\target\h\WPILib\SmartDashboard
diff --git a/aos/externals/WPILib/WPILib/SerialPort.cpp b/aos/externals/WPILib/WPILib/SerialPort.cpp
index 7a1047e..f948f0a 100644
--- a/aos/externals/WPILib/WPILib/SerialPort.cpp
+++ b/aos/externals/WPILib/WPILib/SerialPort.cpp
@@ -183,13 +183,18 @@
 	uint32_t retCount = 0;
 	if (!m_consoleModeEnabled)
 	{
-		ViStatus localStatus = viBufRead(m_portHandle, (ViPBuf)buffer, count, (ViPUInt32)&retCount);
+		ViStatus localStatus = viRead(m_portHandle, (ViPBuf)buffer, count, (ViPUInt32)&retCount);
 		switch (localStatus)
 		{
 		case VI_SUCCESS_TERM_CHAR:
 		case VI_SUCCESS_MAX_CNT:
 		case VI_ERROR_TMO: // Timeout
 			break;
+		case VI_ERROR_IO:
+		case VI_ERROR_ASRL_OVERRUN:	
+			wpi_setError(localStatus);
+			Reset();
+			break;
 		default:
 			wpi_setError(localStatus);
 		}
@@ -209,7 +214,7 @@
 	uint32_t retCount = 0;
 	if (!m_consoleModeEnabled)
 	{
-		ViStatus localStatus = viBufWrite(m_portHandle, (ViPBuf)buffer, count, (ViPUInt32)&retCount);
+		ViStatus localStatus = viWrite(m_portHandle, (ViPBuf)buffer, count, (ViPUInt32)&retCount);
 		wpi_setError(localStatus);
 	}
 	return retCount;
diff --git a/aos/externals/WPILib/WPILib/networktables2/AbstractNetworkTableEntryStore.cpp b/aos/externals/WPILib/WPILib/networktables2/AbstractNetworkTableEntryStore.cpp
index 00829a0..8d268b2 100644
--- a/aos/externals/WPILib/WPILib/networktables2/AbstractNetworkTableEntryStore.cpp
+++ b/aos/externals/WPILib/WPILib/networktables2/AbstractNetworkTableEntryStore.cpp
@@ -32,7 +32,7 @@
 	 */
 	NetworkTableEntry* AbstractNetworkTableEntryStore::GetEntry(std::string& name){
 		{ 
-			NTSynchronized sync(LOCK);
+			NTSynchronized sync(block_namedEntries);
 			std::map<std::string, NetworkTableEntry*>::iterator value_itr = namedEntries.find(name);
 			if(value_itr != namedEntries.end()) {
 				return value_itr->second;
@@ -43,7 +43,7 @@
 	
 	NetworkTableEntry* AbstractNetworkTableEntryStore::GetEntry(EntryId entryId){
 		{ 
-			NTSynchronized sync(LOCK);
+			NTSynchronized sync(block_namedEntries);
 			
 			std::map<EntryId, NetworkTableEntry*>::iterator value_itr = idEntries.find(entryId);
 			if(value_itr != idEntries.end()) {
@@ -55,7 +55,7 @@
 	
 	std::vector<std::string>* AbstractNetworkTableEntryStore::keys(){
 		{ 
-			NTSynchronized sync(LOCK);
+			NTSynchronized sync(block_namedEntries);
 			std::vector<std::string>* keys = new std::vector<std::string>();
 			std::map<std::string, NetworkTableEntry*>::iterator itr;
 			
@@ -77,7 +77,7 @@
 	 */
 	void AbstractNetworkTableEntryStore::clearEntries(){
 		{ 
-			NTSynchronized sync(LOCK);
+			NTSynchronized sync(block_namedEntries);
 			namedEntries.clear();
 			idEntries.clear();
 		}
@@ -88,7 +88,7 @@
 	 */
 	void AbstractNetworkTableEntryStore::clearIds(){
 		{ 
-			NTSynchronized sync(LOCK);
+			NTSynchronized sync(block_namedEntries);
 			std::map<std::string, NetworkTableEntry*>::iterator itr;
 			idEntries.clear();
 			
@@ -119,7 +119,7 @@
 	 */
 	void AbstractNetworkTableEntryStore::PutOutgoing(std::string& name, NetworkTableEntryType* type, EntryValue value){
 		{ 
-			NTSynchronized sync(LOCK);
+			NTSynchronized sync(block_namedEntries);
 			std::map<std::string, NetworkTableEntry*>::iterator index = namedEntries.find(name);
 			NetworkTableEntry* tableEntry;
 			if(index == namedEntries.end())//if the name does not exist in the current entries
@@ -167,7 +167,7 @@
 	
 	void AbstractNetworkTableEntryStore::offerIncomingAssignment(NetworkTableEntry* entry){
 		{ 
-			NTSynchronized sync(LOCK);
+			NTSynchronized sync(block_namedEntries);
 			std::map<std::string, NetworkTableEntry*>::iterator itr = namedEntries.find(entry->name);
 			NetworkTableEntry* tableEntry;
 			if(addEntry(entry)){
@@ -203,7 +203,7 @@
 	 */
 	void AbstractNetworkTableEntryStore::notifyEntries(ITable* table, ITableListener* listener){
 		{ 
-			NTSynchronized sync(LOCK);
+			NTSynchronized sync(block_namedEntries);
 			std::map<std::string, NetworkTableEntry*>::iterator itr;
 			for(itr = namedEntries.begin(); itr != namedEntries.end(); itr++)
 			{
diff --git a/aos/externals/WPILib/WPILib/networktables2/AbstractNetworkTableEntryStore.h b/aos/externals/WPILib/WPILib/networktables2/AbstractNetworkTableEntryStore.h
index b394cfb..7d6903f 100644
--- a/aos/externals/WPILib/WPILib/networktables2/AbstractNetworkTableEntryStore.h
+++ b/aos/externals/WPILib/WPILib/networktables2/AbstractNetworkTableEntryStore.h
@@ -36,6 +36,7 @@
 class AbstractNetworkTableEntryStore : public IncomingEntryReceiver{
 protected:
 	std::map<EntryId,NetworkTableEntry*> idEntries;
+	NTReentrantSemaphore block_namedEntries;
 	std::map<std::string,NetworkTableEntry*> namedEntries;
 	TableListenerManager& listenerManager;
 
diff --git a/aos/externals/WPILib/WPILib/networktables2/NetworkTableEntry.cpp b/aos/externals/WPILib/WPILib/networktables2/NetworkTableEntry.cpp
index 9538c91..658c7c7 100644
--- a/aos/externals/WPILib/WPILib/networktables2/NetworkTableEntry.cpp
+++ b/aos/externals/WPILib/WPILib/networktables2/NetworkTableEntry.cpp
@@ -20,6 +20,17 @@
 	m_isDirty = false;
 }
 
+NetworkTableEntry::NetworkTableEntry(const NetworkTableEntry &other) :
+	name(other.name),
+	id(other.id),
+	sequenceNumber(other.sequenceNumber),
+	type(other.type),
+	m_isNew(other.m_isNew),
+	m_isDirty(other.m_isDirty)
+{
+	value = type->copyValue(other.value);
+}
+
 NetworkTableEntry::~NetworkTableEntry(){
   type->deleteValue(value);
 }
diff --git a/aos/externals/WPILib/WPILib/networktables2/NetworkTableEntry.h b/aos/externals/WPILib/WPILib/networktables2/NetworkTableEntry.h
index 2a29004..27223e4 100644
--- a/aos/externals/WPILib/WPILib/networktables2/NetworkTableEntry.h
+++ b/aos/externals/WPILib/WPILib/networktables2/NetworkTableEntry.h
@@ -42,6 +42,7 @@
 	
 	NetworkTableEntry(std::string& name, NetworkTableEntryType* type, EntryValue value);
 	NetworkTableEntry(EntryId id, std::string& name, SequenceNumber sequenceNumber, NetworkTableEntryType* type, EntryValue value);
+	NetworkTableEntry(const NetworkTableEntry &);
 	virtual ~NetworkTableEntry();
 
 	EntryId GetId();
diff --git a/aos/externals/WPILib/WPILib/networktables2/WriteManager.cpp b/aos/externals/WPILib/WPILib/networktables2/WriteManager.cpp
index bbe08f5..64688e3 100644
--- a/aos/externals/WPILib/WPILib/networktables2/WriteManager.cpp
+++ b/aos/externals/WPILib/WPILib/networktables2/WriteManager.cpp
@@ -54,10 +54,15 @@
 
 void WriteManager::offerOutgoingAssignment(NetworkTableEntry* entry) {
 	{ 
-		NTSynchronized sync(transactionsLock);
-		((std::queue<NetworkTableEntry*>*)incomingAssignmentQueue)->push(entry);
-		
-		if(((std::queue<NetworkTableEntry*>*)incomingAssignmentQueue)->size()>=queueSize){
+		bool test_queue_overflow=false;
+		{
+			NTSynchronized sync(transactionsLock);
+			((std::queue<NetworkTableEntry*>*)incomingAssignmentQueue)->push(entry);
+
+			test_queue_overflow=(((std::queue<NetworkTableEntry*>*)incomingAssignmentQueue)->size()>=queueSize);
+		}
+		if (test_queue_overflow)
+		{
 			run();
 			writeWarning("assignment queue overflowed. decrease the rate at which you create new entries or increase the write buffer size");
 		}
@@ -67,9 +72,15 @@
 
 void WriteManager::offerOutgoingUpdate(NetworkTableEntry* entry) {
 	{ 
-		NTSynchronized sync(transactionsLock);
-		((std::queue<NetworkTableEntry*>*)incomingUpdateQueue)->push(entry);
-		if(((std::queue<NetworkTableEntry*>*)incomingUpdateQueue)->size()>=queueSize){
+		bool test_queue_overflow=false;
+		{
+			NTSynchronized sync(transactionsLock);
+			((std::queue<NetworkTableEntry*>*)incomingUpdateQueue)->push(entry);
+			test_queue_overflow=(((std::queue<NetworkTableEntry*>*)incomingUpdateQueue)->size()>=queueSize);
+
+		}
+		if (test_queue_overflow)
+		{
 			run();
 			writeWarning("update queue overflowed. decrease the rate at which you update entries or increase the write buffer size");
 		}
@@ -97,10 +108,17 @@
 		entry = ((std::queue<NetworkTableEntry*>*)outgoingAssignmentQueue)->front();
 		((std::queue<NetworkTableEntry*>*)outgoingAssignmentQueue)->pop();
 		{
-			NTSynchronized sync(entryStore.LOCK);
-			entry->MakeClean();
-			wrote = true;
-			receiver.offerOutgoingAssignment(entry);
+			NetworkTableEntry * entryCopy;
+
+			{
+				NTSynchronized sync(entryStore.LOCK);
+				entry->MakeClean();
+				wrote = true;
+				entryCopy = new NetworkTableEntry(*entry);
+			}
+
+			receiver.offerOutgoingAssignment(entryCopy);
+			delete entryCopy;
 		}
 	}
 	
@@ -108,10 +126,17 @@
 		entry = ((std::queue<NetworkTableEntry*>*)outgoingUpdateQueue)->front();
 		((std::queue<NetworkTableEntry*>*)outgoingUpdateQueue)->pop();
 		{ 
-			NTSynchronized sync(entryStore.LOCK);
-			entry->MakeClean();
-			wrote = true;
-			receiver.offerOutgoingUpdate(entry);
+			NetworkTableEntry * entryCopy;
+
+			{
+				NTSynchronized sync(entryStore.LOCK);
+				entry->MakeClean();
+				wrote = true;
+				entryCopy = new NetworkTableEntry(*entry);
+			}
+
+			receiver.offerOutgoingUpdate(entryCopy);
+			delete entryCopy;
 		}
 	}
 	
diff --git a/aos/externals/WPILib/WPILib/networktables2/client/ClientNetworkTableEntryStore.cpp b/aos/externals/WPILib/WPILib/networktables2/client/ClientNetworkTableEntryStore.cpp
index d2fc19d..15c0e1f 100644
--- a/aos/externals/WPILib/WPILib/networktables2/client/ClientNetworkTableEntryStore.cpp
+++ b/aos/externals/WPILib/WPILib/networktables2/client/ClientNetworkTableEntryStore.cpp
@@ -17,7 +17,7 @@
 
 bool ClientNetworkTableEntryStore::addEntry(NetworkTableEntry* newEntry){
 	{
-		NTSynchronized sync(LOCK);
+		NTSynchronized sync(block_namedEntries);
 		NetworkTableEntry* entry = (NetworkTableEntry*)namedEntries[newEntry->name];
 
 		if(entry!=NULL){
diff --git a/aos/externals/WPILib/WPILib/networktables2/connection/NetworkTableConnection.cpp b/aos/externals/WPILib/WPILib/networktables2/connection/NetworkTableConnection.cpp
index 6f675b0..13c61fc 100644
--- a/aos/externals/WPILib/WPILib/networktables2/connection/NetworkTableConnection.cpp
+++ b/aos/externals/WPILib/WPILib/networktables2/connection/NetworkTableConnection.cpp
@@ -19,6 +19,7 @@
 
 void NetworkTableConnection::SetIOStream(IOStream* stream)
 {
+	isValid=(stream!=NULL);
 	ioStream->SetIOStream(stream);  //just passing through
 }
 
@@ -102,7 +103,7 @@
 }
 
 void NetworkTableConnection::read(ConnectionAdapter& adapter) {
-	int messageType = ioStream->readByte();
+	int messageType = (isValid)?ioStream->readByte():KEEP_ALIVE;
 	switch (messageType) {
 	case KEEP_ALIVE:
 		adapter.keepAlive();
diff --git a/aos/externals/WPILib/WPILib/networktables2/server/NetworkTableServer.cpp b/aos/externals/WPILib/WPILib/networktables2/server/NetworkTableServer.cpp
index ea85356..a0f3677 100644
--- a/aos/externals/WPILib/WPILib/networktables2/server/NetworkTableServer.cpp
+++ b/aos/externals/WPILib/WPILib/networktables2/server/NetworkTableServer.cpp
@@ -35,6 +35,9 @@
 
 void NetworkTableServer::Close(){
 	try{
+		//Note: streamProvider must come before the incomingStreamMonitor so the that task can complete first for the thread to close 
+		//  [9/1/2013 Terminator] 
+		streamProvider.close(); 
 		incomingStreamMonitor.stop();
 		writeManager.stop();
 		connectionList.closeAll();
diff --git a/aos/externals/WPILib/WPILib/networktables2/server/ServerConnectionAdapter.cpp b/aos/externals/WPILib/WPILib/networktables2/server/ServerConnectionAdapter.cpp
index 195f6e7..62323d8 100644
--- a/aos/externals/WPILib/WPILib/networktables2/server/ServerConnectionAdapter.cpp
+++ b/aos/externals/WPILib/WPILib/networktables2/server/ServerConnectionAdapter.cpp
@@ -36,6 +36,9 @@
 	gotoState(new ServerConnectionState_Error(e));
 	adapterListener.close(*this, true);
 	m_IsAdapterListenerClosed=true;
+	if (readThread)    {
+	  readThread->stop();
+	}
 }
 
 void ServerConnectionAdapter::ioException(IOException& e) {
@@ -47,6 +50,9 @@
 		gotoState(new ServerConnectionState_Error(e));
 	adapterListener.close(*this, false);
 	m_IsAdapterListenerClosed=true;
+	if (readThread)    {
+	  readThread->stop();
+	}
 }
 
 
diff --git a/aos/externals/WPILib/WPILib/networktables2/server/ServerIncomingStreamMonitor.cpp b/aos/externals/WPILib/WPILib/networktables2/server/ServerIncomingStreamMonitor.cpp
index 51c5733..44bf367 100644
--- a/aos/externals/WPILib/WPILib/networktables2/server/ServerIncomingStreamMonitor.cpp
+++ b/aos/externals/WPILib/WPILib/networktables2/server/ServerIncomingStreamMonitor.cpp
@@ -7,6 +7,7 @@
 
 #include "networktables2/server/ServerIncomingStreamMonitor.h"
 #include "networktables2/stream/IOStream.h"
+#include "networktables2/util/System.h"
 
 ServerIncomingStreamMonitor::ServerIncomingStreamMonitor(IOStreamProvider& _streamProvider, ServerNetworkTableEntryStore& _entryStore,
 		ServerIncomingConnectionListener& _incomingListener, ServerAdapterManager& _adapterListener, NetworkTableEntryTypeManager& _typeManager,
@@ -69,6 +70,7 @@
 				ServerConnectionAdapter* connectionAdapter = new ServerConnectionAdapter(newStream, entryStore, entryStore, adapterListener, typeManager, threadManager);
 				incomingListener.OnNewConnection(*connectionAdapter);
 			}
+			sleep_ms(100); //avoid busy wait
 		}
 	}
 	catch (IOException& e)
diff --git a/aos/externals/WPILib/WPILib/networktables2/server/ServerNetworkTableEntryStore.cpp b/aos/externals/WPILib/WPILib/networktables2/server/ServerNetworkTableEntryStore.cpp
index b1d86c9..b49bbf5 100644
--- a/aos/externals/WPILib/WPILib/networktables2/server/ServerNetworkTableEntryStore.cpp
+++ b/aos/externals/WPILib/WPILib/networktables2/server/ServerNetworkTableEntryStore.cpp
@@ -18,7 +18,7 @@
 
 bool ServerNetworkTableEntryStore::addEntry(NetworkTableEntry* newEntry)
 {
-	NTSynchronized sync(LOCK);
+	NTSynchronized sync(block_namedEntries);
 	NetworkTableEntry* entry = namedEntries[newEntry->name];
 	
 	if (entry == NULL)
@@ -44,13 +44,20 @@
  */
 void ServerNetworkTableEntryStore::sendServerHello(NetworkTableConnection& connection)
 {
-	NTSynchronized sync(LOCK);
-	std::map<std::string, NetworkTableEntry*>::iterator itr;
-	for (itr = namedEntries.begin(); itr != namedEntries.end(); itr++)
+	std::vector<NetworkTableEntry *> entry_list;
 	{
-		NetworkTableEntry* entry = itr->second;
-		connection.sendEntryAssignment(*entry);
+		NTSynchronized sync(block_namedEntries);
+		std::map<std::string, NetworkTableEntry*>::iterator itr;
+		for (itr = namedEntries.begin(); itr != namedEntries.end(); itr++)
+		{
+			NetworkTableEntry* entry = itr->second;
+			entry_list.push_back(entry);
+		}
 	}
+
+	for (size_t i=0;i<entry_list.size();i++)
+		connection.sendEntryAssignment(*(entry_list[i]));
+
 	connection.sendServerHelloComplete();
 	connection.flush();
 }
diff --git a/aos/externals/WPILib/WPILib/networktables2/stream/FDIOStream.cpp b/aos/externals/WPILib/WPILib/networktables2/stream/FDIOStream.cpp
index d0dd657..55e2ac2 100644
--- a/aos/externals/WPILib/WPILib/networktables2/stream/FDIOStream.cpp
+++ b/aos/externals/WPILib/WPILib/networktables2/stream/FDIOStream.cpp
@@ -11,7 +11,7 @@
 
 #include <errno.h>
 #include <stdlib.h>
-#include <iolib.h>
+#include <ioLib.h>
 #include <selectLib.h>
 #include <string.h>
 #include <stdio.h>
@@ -22,6 +22,13 @@
   //	f = fdopen(_fd, "rbwb");
   //	if(f==NULL)
   //		throw IOException("Could not open stream from file descriptor", errno);
+  // Set the TCP socket to be non-blocking
+  int on = 1;
+  if (ioctl(fd, FIONBIO, (int)&on) < 0)
+  {
+    ::close(fd);
+    throw IOException("Could not set socket to non-blocking mode");
+  }
 }
 FDIOStream::~FDIOStream(){
 	close();
@@ -64,14 +71,35 @@
 	return totalRead;
 }
 int FDIOStream::write(const void* ptr, int numbytes){
-  int numWrote = ::write(fd, (char*)ptr, numbytes);//TODO: this is bad
-  //int numWrote = fwrite(ptr, 1, numbytes, f);
-  if(numWrote==numbytes)
-    return numWrote;
-  perror("write error: ");
-  fflush(stderr);
-  throw IOException("Could not write all bytes to fd stream");
-	
+	int numWrote = ::write(fd, (char*)ptr, numbytes);
+	if(numWrote==numbytes)
+		return numWrote;
+
+	if (numWrote == -1 && (errno == EWOULDBLOCK || errno == EAGAIN))
+	{
+		// see if write timeout expires
+		struct timeval timeout;
+		fd_set fdSet;
+
+		FD_ZERO(&fdSet);
+		FD_SET(fd, &fdSet);
+		timeout.tv_sec = 1;		// wait 1 second for the other side to connect
+		timeout.tv_usec = 0;
+
+		int select_result = select(FD_SETSIZE, NULL, &fdSet, NULL, &timeout);
+		if ( select_result < 0)
+			throw IOException("Select returned an error on write");
+
+		if (FD_ISSET(fd, &fdSet)) {
+			numWrote = ::write(fd, (char*)ptr, numbytes);
+			if(numWrote==numbytes)
+				return numWrote;
+		}
+	}
+ 	
+	perror("write error: ");
+	fflush(stderr);
+	throw IOException("Could not write all bytes to fd stream");
 }
 void FDIOStream::flush(){
   //if(fflush(f)==EOF)