Commit f5cc18a3 authored by Orvid King's avatar Orvid King Committed by Facebook Github Bot

Support NetworkSocket in ShutdownSocketSet

Summary: More places supporting NetworkSocket.

Reviewed By: yfeldblum

Differential Revision: D12818369

fbshipit-source-id: 6ee0ce2dde3283ea7fd8f657329dc55c78c90714
parent d580d889
......@@ -22,6 +22,7 @@
#include <glog/logging.h>
#include <folly/FileUtil.h>
#include <folly/net/NetOps.h>
#include <folly/portability/Sockets.h>
namespace folly {
......@@ -32,27 +33,27 @@ ShutdownSocketSet::ShutdownSocketSet(int maxFd)
folly::checkedCalloc(size_t(maxFd), sizeof(std::atomic<uint8_t>)))),
nullFile_("/dev/null", O_RDWR) {}
void ShutdownSocketSet::add(int fd) {
void ShutdownSocketSet::add(NetworkSocket fd) {
// Silently ignore any fds >= maxFd_, very unlikely
DCHECK_GE(fd, 0);
if (fd >= maxFd_) {
DCHECK_NE(fd, NetworkSocket());
if (fd.data >= maxFd_) {
return;
}
auto& sref = data_[size_t(fd)];
auto& sref = data_[size_t(fd.data)];
uint8_t prevState = FREE;
CHECK(sref.compare_exchange_strong(
prevState, IN_USE, std::memory_order_relaxed))
<< "Invalid prev state for fd " << fd << ": " << int(prevState);
}
void ShutdownSocketSet::remove(int fd) {
DCHECK_GE(fd, 0);
if (fd >= maxFd_) {
void ShutdownSocketSet::remove(NetworkSocket fd) {
DCHECK_NE(fd, NetworkSocket());
if (fd.data >= maxFd_) {
return;
}
auto& sref = data_[size_t(fd)];
auto& sref = data_[size_t(fd.data)];
uint8_t prevState = 0;
prevState = sref.load(std::memory_order_relaxed);
......@@ -70,13 +71,13 @@ void ShutdownSocketSet::remove(int fd) {
!sref.compare_exchange_weak(prevState, FREE, std::memory_order_relaxed));
}
int ShutdownSocketSet::close(int fd) {
DCHECK_GE(fd, 0);
if (fd >= maxFd_) {
int ShutdownSocketSet::close(NetworkSocket fd) {
DCHECK_NE(fd, NetworkSocket());
if (fd.data >= maxFd_) {
return folly::closeNoInt(fd);
}
auto& sref = data_[size_t(fd)];
auto& sref = data_[size_t(fd.data)];
uint8_t prevState = sref.load(std::memory_order_relaxed);
uint8_t newState = 0;
......@@ -99,14 +100,14 @@ int ShutdownSocketSet::close(int fd) {
return newState == FREE ? folly::closeNoInt(fd) : 0;
}
void ShutdownSocketSet::shutdown(int fd, bool abortive) {
DCHECK_GE(fd, 0);
if (fd >= maxFd_) {
void ShutdownSocketSet::shutdown(NetworkSocket fd, bool abortive) {
DCHECK_NE(fd, NetworkSocket());
if (fd.data >= maxFd_) {
doShutdown(fd, abortive);
return;
}
auto& sref = data_[size_t(fd)];
auto& sref = data_[size_t(fd.data)];
uint8_t prevState = IN_USE;
if (!sref.compare_exchange_strong(
prevState, IN_SHUTDOWN, std::memory_order_relaxed)) {
......@@ -135,12 +136,14 @@ void ShutdownSocketSet::shutdownAll(bool abortive) {
for (int i = 0; i < maxFd_; ++i) {
auto& sref = data_[size_t(i)];
if (sref.load(std::memory_order_relaxed) == IN_USE) {
shutdown(i, abortive);
shutdown(
NetworkSocket(static_cast<NetworkSocket::native_handle_type>(i)),
abortive);
}
}
}
void ShutdownSocketSet::doShutdown(int fd, bool abortive) {
void ShutdownSocketSet::doShutdown(NetworkSocket fd, bool abortive) {
// shutdown() the socket first, to awaken any threads blocked on the fd
// (subsequent IO will fail because it's been shutdown); close()ing the
// socket does not wake up blockers, see
......@@ -152,17 +155,23 @@ void ShutdownSocketSet::doShutdown(int fd, bool abortive) {
// close.
if (abortive) {
struct linger l = {1, 0};
if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) != 0) {
if (netops::setsockopt(fd, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) != 0) {
// Probably not a socket, ignore.
return;
}
}
// Note that this can be ignored without breaking anything due to the
// fact the file descriptor will eventually be closed, so on Windows
// all of the socket resources will just stick around longer than they
// do on posix-like systems.
#ifndef _WIN32
// We can't close() the socket, as that would be dangerous; a new file
// could be opened and get the same file descriptor, and then code assuming
// the old fd would do IO in the wrong place. We'll (atomically) dup2
// /dev/null onto the fd instead.
folly::dup2NoInt(nullFile_.fd(), fd);
folly::dup2NoInt(nullFile_.fd(), fd.toFd());
#endif
}
} // namespace folly
......@@ -23,6 +23,7 @@
#include <boost/noncopyable.hpp>
#include <folly/File.h>
#include <folly/net/NetworkSocket.h>
namespace folly {
......@@ -45,7 +46,10 @@ class ShutdownSocketSet : private boost::noncopyable {
* ShutdownSocketSet::close (which will, as a side effect, also handle EINTR
* properly) and not by calling close() on the file descriptor.
*/
void add(int fd);
void add(NetworkSocket fd);
void add(int fd) {
add(NetworkSocket::fromFd(fd));
}
/**
* Remove a socket from the list of sockets managed by ShutdownSocketSet.
......@@ -53,13 +57,19 @@ class ShutdownSocketSet : private boost::noncopyable {
* sleep()-ing) in the extremely rare case that the fd is currently
* being shutdown().
*/
void remove(int fd);
void remove(NetworkSocket fd);
void remove(int fd) {
remove(NetworkSocket::fromFd(fd));
}
/**
* Close a socket managed by ShutdownSocketSet. Returns the same return code
* as ::close() (and sets errno accordingly).
*/
int close(int fd);
int close(NetworkSocket fd);
int close(int fd) {
return close(NetworkSocket::fromFd(fd));
}
/**
* Shut down a socket. If abortive is true, we perform an abortive
......@@ -70,7 +80,10 @@ class ShutdownSocketSet : private boost::noncopyable {
* read() and write() operations to the socket will fail. During normal
* operation, just call ::shutdown() on the socket.
*/
void shutdown(int fd, bool abortive = false);
void shutdown(NetworkSocket fd, bool abortive = false);
void shutdown(int fd, bool abortive = false) {
shutdown(NetworkSocket::fromFd(fd), abortive);
}
/**
* Immediate shutdown of all connections. This is a hard-hitting hammer;
......@@ -95,7 +108,7 @@ class ShutdownSocketSet : private boost::noncopyable {
void shutdownAll(bool abortive = false);
private:
void doShutdown(int fd, bool abortive);
void doShutdown(NetworkSocket fd, bool abortive);
// State transitions:
// add():
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment