Explorar el Código

Add set_timeout()

Daniele Bartolini hace 12 años
padre
commit
85d6116a8c
Se han modificado 1 ficheros con 33 adiciones y 2 borrados
  1. 33 2
      engine/os/posix/OsSocket.h

+ 33 - 2
engine/os/posix/OsSocket.h

@@ -42,13 +42,13 @@ namespace crown
 
 struct ReadResult
 {
-	enum { NO_ERROR, UNKNOWN, REMOTE_CLOSED } error;
+	enum { NO_ERROR, REMOTE_CLOSED, TIMEOUT, UNKNOWN } error;
 	size_t bytes_read;
 };
 
 struct WriteResult
 {
-	enum { NO_ERROR, UNKNOWN, REMOTE_CLOSED } error;
+	enum { NO_ERROR, REMOTE_CLOSED, TIMEOUT, UNKNOWN } error;
 	size_t bytes_wrote;
 };
 
@@ -117,6 +117,10 @@ public:
 			result.error = ReadResult::NO_ERROR;
 			result.bytes_read = 0;
 		}
+		else if (read_bytes == -1 && errno == ETIMEDOUT)
+		{
+			result.error = ReadResult::TIMEOUT;
+		}
 		else if (read_bytes == 0)
 		{
 			result.error = ReadResult::REMOTE_CLOSED;
@@ -147,6 +151,11 @@ public:
 			ssize_t read_bytes = ::read(m_socket, buf, to_read);
 			
 			if (read_bytes == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) continue;
+			else if (read_bytes == -1 && errno == ETIMEDOUT)
+			{
+				result.error = ReadResult::TIMEOUT;
+				return result;
+			}
 			else if (read_bytes == 0)
 			{
 				result.error = ReadResult::REMOTE_CLOSED;
@@ -174,6 +183,10 @@ public:
 			result.error = WriteResult::NO_ERROR;
 			result.bytes_wrote = 0;
 		}
+		else if (bytes_wrote == -1 && errno == ETIMEDOUT)
+		{
+			result.error = WriteResult::TIMEOUT;
+		}
 		else if (bytes_wrote == 0)
 		{
 			result.error = WriteResult::REMOTE_CLOSED;
@@ -211,6 +224,11 @@ public:
 					{
 						continue;
 					}
+					case ETIMEDOUT:
+					{
+						result.error = WriteResult::TIMEOUT;
+						return result;
+					}
 					default:
 					{
 						result.error = WriteResult::UNKNOWN;
@@ -242,6 +260,19 @@ public:
 		setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
 	}
 
+	//-----------------------------------------------------------------------------
+	void set_timeout(uint32_t seconds)
+	{
+		struct timeval timeout;
+		timeout.tv_sec = seconds;
+		timeout.tv_usec = 0;
+		int res;
+		res = setsockopt (m_socket, SOL_SOCKET, SO_RCVTIMEO, (char*) &timeout, sizeof(timeout));
+		CE_ASSERT(res == 0, "Failed to set timeout on socket: errno: %d", errno);
+		res = setsockopt (m_socket, SOL_SOCKET, SO_SNDTIMEO, (char*) &timeout, sizeof(timeout));
+		CE_ASSERT(res == 0, "Failed to set timeout on socket: errno: %d", errno);
+	}
+
 public:
 
 	int m_socket;