44 bool FdReader::winsock_initialized =
false;
63 FdReader::Start(
int fd, Callback<void, uint8_t*, ssize_t> readCallback)
68 if (!winsock_initialized)
71 tmp = WSAStartup(MAKEWORD(2, 2), &wsaData);
73 winsock_initialized =
true;
76 NS_ASSERT_MSG(!m_readThread.joinable(),
"read thread already exists");
79 m_evpipe[0] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
80 m_evpipe[1] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
81 if ((
static_cast<uint64_t
>(m_evpipe[0]) == INVALID_SOCKET) ||
82 (
static_cast<uint64_t
>(m_evpipe[1]) == INVALID_SOCKET))
89 tmp = ioctlsocket(m_evpipe[0], FIONBIO, &iMode);
96 m_readCallback = readCallback;
104 if (!m_destroyEvent.IsRunning())
109 m_destroyEvent = Simulator::ScheduleDestroy(&FdReader::DestroyEvent,
this);
117 m_readThread = std::thread(&FdReader::Run,
this);
121 FdReader::DestroyEvent()
135 if (m_evpipe[1] != -1)
138 ssize_t len = send(m_evpipe[1], &
zero,
sizeof(
zero), 0);
139 if (len !=
sizeof(
zero))
141 NS_LOG_WARN(
"incomplete write(): " << std::strerror(errno));
145 if (m_readThread.joinable())
151 if (m_evpipe[1] != -1)
153 closesocket(m_evpipe[1]);
158 if (m_evpipe[0] != -1)
160 closesocket(m_evpipe[0]);
166 m_readCallback.Nullify();
178 nfds = (m_fd > m_evpipe[0] ? m_fd : m_evpipe[0]) + 1;
182 FD_SET(m_evpipe[0], &rfds);
187 fd_set readfds = rfds;
189 r = select(nfds, &readfds,
nullptr,
nullptr,
nullptr);
190 if (r == -1 && errno != EINTR)
195 if (FD_ISSET(m_evpipe[0], &readfds))
201 ssize_t len = recv(m_evpipe[0], buf,
sizeof(buf), 0);
208 if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)
226 if (FD_ISSET(m_fd, &readfds))
228 FdReader::Data
data = DoRead();
236 else if (
data.m_len > 0)
238 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.