Index: net/base/default_listen_socket.cc |
diff --git a/net/base/tcp_listen_socket.cc b/net/base/default_listen_socket.cc |
similarity index 66% |
copy from net/base/tcp_listen_socket.cc |
copy to net/base/default_listen_socket.cc |
index dfec16ffc7a114c8f21ce9ba756de9486cf11abc..78a8e30f52f7f0e0191a24299bc04181da551ede 100644 |
--- a/net/base/tcp_listen_socket.cc |
+++ b/net/base/default_listen_socket.cc |
@@ -2,7 +2,7 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "build/build_config.h" |
+#include "net/base/default_listen_socket.h" |
#if defined(OS_WIN) |
// winsock2.h must be included first in order to ensure it is included before |
@@ -17,11 +17,13 @@ |
#include "net/base/net_errors.h" |
#endif |
+#include "build/build_config.h" |
#include "base/eintr_wrapper.h" |
#include "base/sys_byteorder.h" |
#include "base/threading/platform_thread.h" |
#include "net/base/net_util.h" |
-#include "net/base/tcp_listen_socket.h" |
+ |
+using std::string; |
#if defined(OS_WIN) |
typedef int socklen_t; |
@@ -36,42 +38,16 @@ const int kReadBufSize = 4096; |
} // namespace |
#if defined(OS_WIN) |
-const SOCKET TCPListenSocket::kInvalidSocket = INVALID_SOCKET; |
-const int TCPListenSocket::kSocketError = SOCKET_ERROR; |
+const SOCKET DefaultListenSocket::kInvalidSocket = INVALID_SOCKET; |
+const int DefaultListenSocket::kSocketError = SOCKET_ERROR; |
#elif defined(OS_POSIX) |
-const SOCKET TCPListenSocket::kInvalidSocket = -1; |
-const int TCPListenSocket::kSocketError = -1; |
+const SOCKET DefaultListenSocket::kInvalidSocket = -1; |
+const int DefaultListenSocket::kSocketError = -1; |
#endif |
-TCPListenSocket* TCPListenSocket::CreateAndListen( |
- std::string ip, int port, ListenSocket::ListenSocketDelegate *del) { |
- SOCKET s = CreateAndBind(ip, port); |
- if (s == kInvalidSocket) { |
- // TODO(erikkay): error handling |
- } else { |
- TCPListenSocket* sock = new TCPListenSocket(s, del); |
- sock->Listen(); |
- return sock; |
- } |
- return NULL; |
-} |
- |
-void TCPListenSocket::PauseReads() { |
- DCHECK(!reads_paused_); |
- reads_paused_ = true; |
-} |
- |
-void TCPListenSocket::ResumeReads() { |
- DCHECK(reads_paused_); |
- reads_paused_ = false; |
- if (has_pending_reads_) { |
- has_pending_reads_ = false; |
- Read(); |
- } |
-} |
- |
-TCPListenSocket::TCPListenSocket(SOCKET s, |
- ListenSocket::ListenSocketDelegate *del) |
+DefaultListenSocket::DefaultListenSocket( |
+ SOCKET s, |
+ ListenSocket::ListenSocketDelegate* del) |
: ListenSocket(del), |
socket_(s), |
reads_paused_(false), |
@@ -85,7 +61,7 @@ TCPListenSocket::TCPListenSocket(SOCKET s, |
#endif |
} |
-TCPListenSocket::~TCPListenSocket() { |
+DefaultListenSocket::~DefaultListenSocket() { |
#if defined(OS_WIN) |
if (socket_event_) { |
WSACloseEvent(socket_event_); |
@@ -95,44 +71,17 @@ TCPListenSocket::~TCPListenSocket() { |
CloseSocket(socket_); |
} |
-SOCKET TCPListenSocket::CreateAndBind(std::string ip, int port) { |
- SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
- if (s != kInvalidSocket) { |
-#if defined(OS_POSIX) |
- // Allow rapid reuse. |
- static const int kOn = 1; |
- setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn)); |
-#endif |
- sockaddr_in addr; |
- memset(&addr, 0, sizeof(addr)); |
- addr.sin_family = AF_INET; |
- addr.sin_addr.s_addr = inet_addr(ip.c_str()); |
- addr.sin_port = base::HostToNet16(port); |
- if (bind(s, reinterpret_cast<sockaddr*>(&addr), sizeof(addr))) { |
-#if defined(OS_WIN) |
- closesocket(s); |
-#elif defined(OS_POSIX) |
- close(s); |
-#endif |
- s = kInvalidSocket; |
- } |
- } |
- return s; |
-} |
- |
-SOCKET TCPListenSocket::Accept(SOCKET s) { |
- sockaddr_in from; |
- socklen_t from_len = sizeof(from); |
- SOCKET conn = |
- HANDLE_EINTR(accept(s, reinterpret_cast<sockaddr*>(&from), &from_len)); |
- if (conn != kInvalidSocket) { |
+SOCKET DefaultListenSocket::Accept(SOCKET s) { |
+ SOCKET conn = HANDLE_EINTR(accept(s, NULL, NULL)); |
+ if (conn == kInvalidSocket) |
+ LOG(ERROR) << "Error accepting connection."; |
+ else |
SetNonBlocking(conn); |
- } |
return conn; |
} |
-void TCPListenSocket::SendInternal(const char* bytes, int len) { |
- char* send_buf = const_cast<char *>(bytes); |
+void DefaultListenSocket::SendInternal(const char* bytes, int len) { |
+ char* send_buf = const_cast<char*>(bytes); |
int len_left = len; |
while (true) { |
int sent = HANDLE_EINTR(send(socket_, send_buf, len_left, 0)); |
@@ -151,6 +100,9 @@ void TCPListenSocket::SendInternal(const char* bytes, int len) { |
} |
// Otherwise we would block, and now we have to wait for a retry. |
// Fall through to PlatformThread::YieldCurrentThread() |
+ } else if (sent == 0) { |
+ // Socket was disconnected. |
+ Close(); |
} else { |
// sent != len_left according to the shortcut above. |
// Shift the buffer start and send the remainder after a short while. |
@@ -161,31 +113,18 @@ void TCPListenSocket::SendInternal(const char* bytes, int len) { |
} |
} |
-void TCPListenSocket::Listen() { |
+void DefaultListenSocket::Listen() { |
int backlog = 10; // TODO(erikkay): maybe don't allow any backlog? |
- listen(socket_, backlog); |
- // TODO(erikkay): error handling |
+ if (listen(socket_, backlog) == -1) { |
+ LOG(ERROR) << "Could not listen on socket."; |
+ return; |
+ } |
#if defined(OS_POSIX) |
WatchSocket(WAITING_ACCEPT); |
#endif |
} |
-void TCPListenSocket::Accept() { |
- SOCKET conn = Accept(socket_); |
- if (conn != kInvalidSocket) { |
- scoped_refptr<TCPListenSocket> sock( |
- new TCPListenSocket(conn, socket_delegate_)); |
- // it's up to the delegate to AddRef if it wants to keep it around |
-#if defined(OS_POSIX) |
- sock->WatchSocket(WAITING_READ); |
-#endif |
- socket_delegate_->DidAccept(this, sock); |
- } else { |
- // TODO(ibrar): some error handling required here |
- } |
-} |
- |
-void TCPListenSocket::Read() { |
+void DefaultListenSocket::Read() { |
char buf[kReadBufSize + 1]; // +1 for null termination |
int len; |
do { |
@@ -218,7 +157,7 @@ void TCPListenSocket::Read() { |
} while (len == kReadBufSize); |
} |
-void TCPListenSocket::Close() { |
+void DefaultListenSocket::Close() { |
#if defined(OS_POSIX) |
if (wait_state_ == NOT_WAITING) |
return; |
@@ -228,7 +167,7 @@ void TCPListenSocket::Close() { |
socket_delegate_->DidClose(this); |
} |
-void TCPListenSocket::CloseSocket(SOCKET s) { |
+void DefaultListenSocket::CloseSocket(SOCKET s) { |
if (s && s != kInvalidSocket) { |
UnwatchSocket(); |
#if defined(OS_WIN) |
@@ -239,7 +178,7 @@ void TCPListenSocket::CloseSocket(SOCKET s) { |
} |
} |
-void TCPListenSocket::WatchSocket(WaitState state) { |
+void DefaultListenSocket::WatchSocket(WaitState state) { |
#if defined(OS_WIN) |
WSAEventSelect(socket_, socket_event_, FD_ACCEPT | FD_CLOSE | FD_READ); |
watcher_.StartWatching(socket_event_, this); |
@@ -251,7 +190,7 @@ void TCPListenSocket::WatchSocket(WaitState state) { |
#endif |
} |
-void TCPListenSocket::UnwatchSocket() { |
+void DefaultListenSocket::UnwatchSocket() { |
#if defined(OS_WIN) |
watcher_.StopWatching(); |
#elif defined(OS_POSIX) |
@@ -262,7 +201,7 @@ void TCPListenSocket::UnwatchSocket() { |
// TODO(ibrar): We can add these functions into OS dependent files |
#if defined(OS_WIN) |
// MessageLoop watcher callback |
-void TCPListenSocket::OnObjectSignaled(HANDLE object) { |
+void DefaultListenSocket::OnObjectSignaled(HANDLE object) { |
WSANETWORKEVENTS ev; |
if (kSocketError == WSAEnumNetworkEvents(socket_, socket_event_, &ev)) { |
// TODO |
@@ -278,7 +217,7 @@ void TCPListenSocket::OnObjectSignaled(HANDLE object) { |
return; |
} |
if (ev.lNetworkEvents & FD_ACCEPT) { |
- Accept(); |
+ AcceptInternal(); |
} |
if (ev.lNetworkEvents & FD_READ) { |
if (reads_paused_) { |
@@ -292,10 +231,10 @@ void TCPListenSocket::OnObjectSignaled(HANDLE object) { |
} |
} |
#elif defined(OS_POSIX) |
-void TCPListenSocket::OnFileCanReadWithoutBlocking(int fd) { |
+void DefaultListenSocket::OnFileCanReadWithoutBlocking(int fd) { |
switch (wait_state_) { |
case WAITING_ACCEPT: |
- Accept(); |
+ AcceptInternal(); |
break; |
case WAITING_READ: |
if (reads_paused_) { |
@@ -311,7 +250,7 @@ void TCPListenSocket::OnFileCanReadWithoutBlocking(int fd) { |
} |
} |
-void TCPListenSocket::OnFileCanWriteWithoutBlocking(int fd) { |
+void DefaultListenSocket::OnFileCanWriteWithoutBlocking(int fd) { |
// MessagePumpLibevent callback, we don't listen for write events |
// so we shouldn't ever reach here. |
NOTREACHED(); |
@@ -319,4 +258,18 @@ void TCPListenSocket::OnFileCanWriteWithoutBlocking(int fd) { |
#endif |
+void DefaultListenSocket::PauseReads() { |
+ DCHECK(!reads_paused_); |
+ reads_paused_ = true; |
+} |
+ |
+void DefaultListenSocket::ResumeReads() { |
+ DCHECK(reads_paused_); |
+ reads_paused_ = false; |
+ if (has_pending_reads_) { |
+ has_pending_reads_ = false; |
+ Read(); |
+ } |
+} |
+ |
} // namespace net |