Skip to content

Commit f3629e0

Browse files
committed
Handle EINTR.
1 parent 5c90908 commit f3629e0

10 files changed

+43
-18
lines changed

bsd/bsd-kqueue.cc

+5-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ KqueueImpl::Shutdown()
4747
detach_for_shutdown(listeners_[i].transport);
4848
}
4949

50-
close(kq_);
50+
AMIO_RETRY_IF_ENTR(close(kq_));
5151
}
5252

5353
PassRef<IOError>
@@ -155,8 +155,11 @@ KqueueImpl::Poll(int timeoutMs)
155155
}
156156

157157
int nevents = kevent(kq_, nullptr, 0, event_buffer_.get(), event_buffer_.length(), timeoutp);
158-
if (nevents == -1)
158+
if (nevents == -1) {
159+
if (errno == EINTR)
160+
return nullptr;
159161
return new PosixError();
162+
}
160163

161164
AutoMaybeLock lock(lock_);
162165

include/amio-eventloop.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,8 @@ class EventQueue : public IODispatcher
154154
virtual void Shutdown() = 0;
155155
};
156156

157-
// An event loop for I/O multiplexing.
157+
// An event loop for I/O multiplexing. This is essentially a wrapper around
158+
// a Poller and a single EventQueue. Tasks are prioritized over events.
158159
class AMIO_LINK EventLoopForIO
159160
: public EventLoop,
160161
public IODispatcher

include/amio-posix.h

+12
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,18 @@ class AutoDisableSigPipe
371371
void (*prev_handler_)(int);
372372
};
373373

374+
// Posix system calls can be interrupted on EINTR. This macro will automatically
375+
// retry syscalls that fail for that reason. This is based on HANDLE_EINTR from
376+
// Chromium.
377+
#define AMIO_RETRY_IF_EINTR(expr) \
378+
({ \
379+
__typeof__(expr) syscall_rv; \
380+
do { \
381+
syscall_rv = expr; \
382+
} while (syscall_rv == -1 && errno == EINTR); \
383+
syscall_rv; \
384+
})
385+
374386
} // namespace amio
375387

376388
#endif // _include_amio_posix_header_h_

linux/linux-epoll.cc

+5-2
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ EpollImpl::Shutdown()
7373
detach_for_shutdown_locked(listeners_[i].transport);
7474
}
7575

76-
close(ep_);
76+
AMIO_RETRY_IF_EINTR(close(ep_));
7777
ep_ = -1;
7878
}
7979

@@ -187,8 +187,11 @@ EpollImpl::Poll(int timeoutMs)
187187
AutoMaybeLock poll_lock(poll_lock_);
188188

189189
int nevents = epoll_wait(ep_, event_buffer_, max_events_, timeoutMs);
190-
if (nevents == -1)
190+
if (nevents == -1) {
191+
if (errno == EINTR)
192+
return nullptr;
191193
return new PosixError();
194+
}
192195

193196
// Now we acquire the transport lock.
194197
AutoMaybeLock lock(lock_);

posix/posix-net.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ ConnectionForSocket(Ref<PosixConnection> *outp, int fd, AddressFamily af)
277277
*outp = new PosixConnectionT<UnixAddress>(fd);
278278
return nullptr;
279279
default:
280-
close(fd);
280+
AMIO_RETRY_IF_EINTR(close(fd));
281281
return eUnsupportedAddressFamily;
282282
}
283283
}
@@ -365,7 +365,7 @@ amio::net::ConnectTo(Ref<Connection> *outp, Protocol protocol, Ref<Address> addr
365365
if (Ref<IOError> error = ConnectionForAddress(&conn, address, protocol))
366366
return error;
367367

368-
int rv = connect(conn->fd(), address->SockAddr(), address->SockAddrLen());
368+
int rv = AMIO_RETRY_IF_EINTR(connect(conn->fd(), address->SockAddr(), address->SockAddrLen()));
369369
if (rv == -1)
370370
return new PosixError();
371371

@@ -405,7 +405,7 @@ class PosixServer
405405
void OnReadReady() override {
406406
size_t failures = 0;
407407
while (failures < 10) {
408-
int rv = accept(transport_->fd(), nullptr, nullptr);
408+
int rv = AMIO_RETRY_IF_EINTR(accept(transport_->fd(), nullptr, nullptr));
409409
if (rv == -1) {
410410
switch (errno) {
411411
#if defined(KE_LINUX)

posix/posix-poll.cc

+4-1
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,11 @@ PollImpl::Poll(int timeoutMs)
199199
}
200200

201201
int nevents = poll(poll_buffer, poll_buffer_len, timeoutMs);
202-
if (nevents == -1)
202+
if (nevents == -1) {
203+
if (errno == EINTR)
204+
return nullptr;
203205
return new PosixError();
206+
}
204207
if (nevents == 0)
205208
return nullptr;
206209

posix/posix-select.cc

+4-1
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,11 @@ SelectImpl::Poll(int timeoutMs)
173173
}
174174

175175
int result = select(fd_watermark + 1, &read_fds, &write_fds, nullptr, timeoutp);
176-
if (result == -1)
176+
if (result == -1) {
177+
if (errno == EINTR)
178+
return nullptr;
177179
return new PosixError();
180+
}
178181

179182
AutoMaybeLock lock(lock_);
180183

posix/posix-transport.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ PosixTransport::Close()
5151
poller->detach_unlocked(this);
5252
}
5353

54-
close(fd_);
54+
AMIO_RETRY_IF_EINTR(close(fd_));
5555
fd_ = -1;
5656

5757
assert(!poller_.get() && !listener_);
@@ -62,7 +62,7 @@ PosixTransport::Read(IOResult *result, void *buffer, size_t maxlength)
6262
{
6363
*result = IOResult();
6464

65-
ssize_t rv = read(fd_, buffer, maxlength);
65+
ssize_t rv = AMIO_RETRY_IF_EINTR(read(fd_, buffer, maxlength));
6666
if (rv == -1) {
6767
if (errno == EWOULDBLOCK || errno == EAGAIN) {
6868
if (Ref<IOError> error = ReadIsBlocked()) {
@@ -91,7 +91,7 @@ PosixTransport::Write(IOResult *result, const void *buffer, size_t maxlength)
9191
{
9292
*result = IOResult();
9393

94-
ssize_t rv = write(fd_, buffer, maxlength);
94+
ssize_t rv = AMIO_RETRY_IF_EINTR(write(fd_, buffer, maxlength));
9595
if (rv == -1) {
9696
if (errno == EWOULDBLOCK || errno == EAGAIN) {
9797
if (Ref<IOError> error = WriteIsBlocked()) {

solaris/amio-solaris-devpoll.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ DevPollImpl::Shutdown()
6161
fds_[i].transport->detach();
6262
}
6363

64-
close(dp_);
64+
AMIO_RETRY_IF_EINTR(close(dp_));
6565
}
6666

6767
static inline PassRef<IOError>
@@ -79,7 +79,7 @@ WriteDevPoll(int dp, int fd, TransportFlags flags)
7979
pe.events = POLLREMOVE;
8080
}
8181

82-
int rv = write(dp, &pe, sizeof(pe));
82+
int rv = AMIO_RETRY_IF_EINTR(write(dp, &pe, sizeof(pe)));
8383
if (rv == -1)
8484
return new PosixError();
8585
if (size_t(rv) != sizeof(pe))
@@ -185,7 +185,7 @@ DevPollImpl::Poll(int timeoutMs)
185185
params.dp_nfds = event_buffer_.length();
186186
params.dp_timeout = timeoutMs;
187187

188-
int nevents = ioctl(dp_, DP_POLL, &params);
188+
int nevents = AMIO_RETRY_IF_EINTR(ioctl(dp_, DP_POLL, &params));
189189
if (nevents == -1)
190190
return new PosixError();
191191

solaris/amio-solaris-port.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ PortImpl::Shutdown()
5353
fds_[i].transport->detach();
5454
}
5555

56-
close(port_);
56+
AMIO_RETRY_IF_EINTR(close(port_));
5757
}
5858

5959
PassRef<IOError>
@@ -186,7 +186,7 @@ PortImpl::Poll(int timeoutMs)
186186
// return more.
187187
uint_t nevents = 1;
188188
if (port_getn(port_, event_buffer->get(), event_buffer->length(), &nevents, timeoutp) == -1) {
189-
if (errno == ETIME)
189+
if (errno == ETIME || errno == EINTR)
190190
return nullptr;
191191
return new PosixError();
192192
}

0 commit comments

Comments
 (0)