/* * Copyright 2004 The WebRTC Project Authors. All rights reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree.
*/
#ifdefined(WEBRTC_POSIX) #ifdefined(WEBRTC_LINUX) // On Linux, use epoll. #include <sys/epoll.h>
#define WEBRTC_USE_EPOLL 1 #elifdefined(WEBRTC_FUCHSIA) || defined(WEBRTC_MAC) // Fuchsia implements select and poll but not epoll, and testing shows that poll // is faster than select. #include <poll.h>
#define WEBRTC_USE_POLL 1 #else // On other POSIX systems, use select by default. #endif// WEBRTC_LINUX, WEBRTC_FUCHSIA, WEBRTC_MAC #endif// WEBRTC_POSIX
// A socket server that provides the real sockets of the underlying OS. class RTC_EXPORT PhysicalSocketServer : public SocketServer { public:
PhysicalSocketServer();
~PhysicalSocketServer() override;
// SocketFactory:
Socket* CreateSocket(int family, int type) override;
// Internal Factory for Accept (virtual so it can be overwritten in tests). virtual Socket* WrapSocket(SOCKET s);
private: // The number of events to process with one call to "epoll_wait". static constexpr size_t kNumEpollEvents = 128; // A local historical definition of "foreverness", in milliseconds. static constexpr int kForeverMs = -1;
// This array is accessed in isolation by a thread calling into Wait(). // It's useless to use a SequenceChecker to guard it because a socket // server can outlive the thread it's bound to, forcing the Wait call // to have to reset the sequence checker on Wait calls.
std::array<epoll_event, kNumEpollEvents> epoll_events_; constint epoll_fd_ = INVALID_SOCKET;
// uint64_t keys are used to uniquely identify a dispatcher in order to avoid // the ABA problem during the epoll loop (a dispatcher being destroyed and // replaced by one with the same address).
uint64_t next_dispatcher_key_ RTC_GUARDED_BY(crit_) = 0;
std::unordered_map<uint64_t, Dispatcher*> dispatcher_by_key_
RTC_GUARDED_BY(crit_); // Reverse lookup necessary for removals/updates.
std::unordered_map<Dispatcher*, uint64_t> key_by_dispatcher_
RTC_GUARDED_BY(crit_); // A list of dispatcher keys that we're interested in for the current // select(), poll(), or WSAWaitForMultipleEvents() loop. Again, used to avoid // the ABA problem (a socket being destroyed and a new one created with the // same handle, erroneously receiving the events from the destroyed socket). // // Kept as a member variable just for efficiency.
std::vector<uint64_t> current_dispatcher_keys_;
Signaler* signal_wakeup_; // Assigned in constructor only
RecursiveCriticalSection crit_; #ifdefined(WEBRTC_WIN) const WSAEVENT socket_ev_; #endif bool fWait_; // Are we currently in a select()/epoll()/WSAWaitForMultipleEvents loop? // Used for a DCHECK, because we don't support reentrant waiting. bool waiting_ = false;
};
class PhysicalSocket : public Socket, public sigslot::has_slots<> { public:
PhysicalSocket(PhysicalSocketServer* ss, SOCKET s = INVALID_SOCKET);
~PhysicalSocket() override;
// Creates the underlying OS socket (same as the "socket" function). virtualbool Create(int family, int type);
int Bind(const SocketAddress& bind_addr) override; int Connect(const SocketAddress& addr) override;
int GetError() const override; void SetError(int error) override;
ConnState GetState() const override;
int GetOption(Option opt, int* value) override; int SetOption(Option opt, int value) override;
int Send(constvoid* pv, size_t cb) override; int SendTo(constvoid* buffer,
size_t length, const SocketAddress& addr) override;
int Recv(void* buffer, size_t length, int64_t* timestamp) override; // TODO(webrtc:15368): Deprecate and remove. int RecvFrom(void* buffer,
size_t length,
SocketAddress* out_addr,
int64_t* timestamp) override; int RecvFrom(ReceiveBuffer& buffer) override;
int Listen(int backlog) override;
Socket* Accept(SocketAddress* out_addr) override;
int Close() override;
SocketServer* socketserver() { return ss_; }
SOCKET GetSocketFD() const { return s_; }
protected: int DoConnect(const SocketAddress& connect_addr);
// Make virtual so ::accept can be overwritten in tests. virtual SOCKET DoAccept(SOCKET socket, sockaddr* addr, socklen_t* addrlen);
// Make virtual so ::send can be overwritten in tests. virtualint DoSend(SOCKET socket, constchar* buf, int len, int flags);
// Make virtual so ::sendto can be overwritten in tests. virtualint DoSendTo(SOCKET socket, constchar* buf, int len, int flags, conststruct sockaddr* dest_addr,
socklen_t addrlen);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.