proxygen
ShutdownSocketSet.h
Go to the documentation of this file.
1 /*
2  * Copyright 2014-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <atomic>
20 #include <cstdlib>
21 #include <memory>
22 
23 #include <boost/noncopyable.hpp>
24 
25 #include <folly/File.h>
26 
27 namespace folly {
28 
32 class ShutdownSocketSet : private boost::noncopyable {
33  public:
40  explicit ShutdownSocketSet(int maxFd = 1 << 18);
41 
48  void add(int fd);
49 
56  void remove(int fd);
57 
62  int close(int fd);
63 
73  void shutdown(int fd, bool abortive = false);
74 
95  void shutdownAll(bool abortive = false);
96 
97  private:
98  void doShutdown(int fd, bool abortive);
99 
100  // State transitions:
101  // add():
102  // FREE -> IN_USE
103  //
104  // close():
105  // IN_USE -> (::close()) -> FREE
106  // SHUT_DOWN -> (::close()) -> FREE
107  // IN_SHUTDOWN -> MUST_CLOSE
108  // (If the socket is currently being shut down, we must defer the
109  // ::close() until the shutdown completes)
110  //
111  // shutdown():
112  // IN_USE -> IN_SHUTDOWN
113  // (::shutdown())
114  // IN_SHUTDOWN -> SHUT_DOWN
115  // MUST_CLOSE -> (::close()) -> FREE
116  //
117  // State atomic operation memory orders:
118  // All atomic operations on per-socket states use std::memory_order_relaxed
119  // because there is no associated per-socket data guarded by the state and
120  // the states for different sockets are unrelated. If there were associated
121  // per-socket data, acquire and release orders would be desired; and if the
122  // states for different sockets were related, it could be that sequential
123  // consistent orders would be desired.
124  enum State : uint8_t {
125  FREE = 0,
130  };
131 
132  struct Free {
133  template <class T>
134  void operator()(T* ptr) const {
135  ::free(ptr);
136  }
137  };
138 
139  const int maxFd_;
140  std::unique_ptr<std::atomic<uint8_t>[], Free> data_;
142 };
143 
144 } // namespace folly
void * ptr
void shutdown(int fd, bool abortive=false)
folly::std T
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
void doShutdown(int fd, bool abortive)
void free()
void shutdownAll(bool abortive=false)
ShutdownSocketSet(int maxFd=1<< 18)
std::unique_ptr< std::atomic< uint8_t >[], Free > data_