35bool FdReader::winsock_initialized =
false;
55FdReader::Start(
int fd, Callback<void, uint8_t*, ssize_t> readCallback)
60 if (!winsock_initialized)
63 tmp = WSAStartup(MAKEWORD(2, 2), &wsaData);
65 winsock_initialized =
true;
68 NS_ASSERT_MSG(!m_readThread.joinable(),
"read thread already exists");
71 m_evpipe[0] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
72 m_evpipe[1] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
73 if ((
static_cast<uint64_t
>(m_evpipe[0]) == INVALID_SOCKET) ||
74 (
static_cast<uint64_t
>(m_evpipe[1]) == INVALID_SOCKET))
81 tmp = ioctlsocket(m_evpipe[0], FIONBIO, &iMode);
88 m_readCallback = readCallback;
96 if (!m_destroyEvent.IsPending())
101 m_destroyEvent = Simulator::ScheduleDestroy(&FdReader::DestroyEvent,
this);
109 m_readThread = std::thread(&FdReader::Run,
this);
113FdReader::DestroyEvent()
127 if (m_evpipe[1] != -1)
130 ssize_t len = send(m_evpipe[1], &
zero,
sizeof(
zero), 0);
131 if (len !=
sizeof(
zero))
133 NS_LOG_WARN(
"incomplete write(): " << std::strerror(errno));
137 if (m_readThread.joinable())
143 if (m_evpipe[1] != -1)
145 closesocket(m_evpipe[1]);
150 if (m_evpipe[0] != -1)
152 closesocket(m_evpipe[0]);
158 m_readCallback.Nullify();
170 nfds = (m_fd > m_evpipe[0] ? m_fd : m_evpipe[0]) + 1;
174 FD_SET(m_evpipe[0], &rfds);
179 fd_set readfds = rfds;
181 r = select(nfds, &readfds,
nullptr,
nullptr,
nullptr);
182 if (r == -1 && errno != EINTR)
187 if (FD_ISSET(m_evpipe[0], &readfds))
193 ssize_t len = recv(m_evpipe[0], buf,
sizeof(buf), 0);
200 if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)
218 if (FD_ISSET(m_fd, &readfds))
220 FdReader::Data
data = DoRead();
228 else if (
data.m_len > 0)
230 m_readCallback(
data.m_buf,
data.m_len);
NS_FATAL_x macro definitions.
ns3::FdReader declaration.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::SimpleRefCount declaration and template implementation.
ns3::Simulator declaration.