Skip to content

Commit e9d9abd

Browse files
committed
Refactor platform error handling
1 parent 142da22 commit e9d9abd

14 files changed

Lines changed: 209 additions & 148 deletions

src/corosio/src/detail/epoll/op.hpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <boost/capy/error.hpp>
2323
#include <boost/system/error_code.hpp>
2424

25+
#include "src/detail/make_err.hpp"
2526
#include "src/detail/scheduler_op.hpp"
2627

2728
#include <unistd.h>
@@ -62,7 +63,7 @@ struct epoll_op : scheduler_op
6263

6364
int fd = -1;
6465
std::uint32_t events = 0;
65-
int error = 0;
66+
int errn = 0;
6667
std::size_t bytes_transferred = 0;
6768

6869
std::atomic<bool> cancelled{false};
@@ -77,7 +78,7 @@ struct epoll_op : scheduler_op
7778
{
7879
fd = -1;
7980
events = 0;
80-
error = 0;
81+
errn = 0;
8182
bytes_transferred = 0;
8283
cancelled.store(false, std::memory_order_relaxed);
8384
}
@@ -89,13 +90,13 @@ struct epoll_op : scheduler_op
8990
if (ec_out)
9091
{
9192
if (cancelled.load(std::memory_order_acquire))
92-
*ec_out = make_error_code(system::errc::operation_canceled);
93-
else if (error != 0)
94-
*ec_out = system::error_code(error, system::system_category());
93+
*ec_out = capy::error::canceled;
94+
else if (errn != 0)
95+
*ec_out = make_err(errn);
9596
else if (is_read_operation() && bytes_transferred == 0)
9697
{
9798
// EOF: 0 bytes transferred with no error indicates end of stream
98-
*ec_out = make_error_code(capy::error::eof);
99+
*ec_out = capy::error::eof;
99100
}
100101
}
101102

@@ -128,7 +129,7 @@ struct epoll_op : scheduler_op
128129

129130
void complete(int err, std::size_t bytes) noexcept
130131
{
131-
error = err;
132+
errn = err;
132133
bytes_transferred = bytes;
133134
}
134135

@@ -267,14 +268,14 @@ struct epoll_accept_op : epoll_op
267268
{
268269
stop_cb.reset();
269270

270-
bool success = (error == 0 && !cancelled.load(std::memory_order_acquire));
271+
bool success = (errn == 0 && !cancelled.load(std::memory_order_acquire));
271272

272273
if (ec_out)
273274
{
274275
if (cancelled.load(std::memory_order_acquire))
275-
*ec_out = make_error_code(system::errc::operation_canceled);
276-
else if (error != 0)
277-
*ec_out = system::error_code(error, system::system_category());
276+
*ec_out = capy::error::canceled;
277+
else if (errn != 0)
278+
*ec_out = make_err(errn);
278279
}
279280

280281
if (success && accepted_fd >= 0 && peer_impl)

src/corosio/src/detail/epoll/scheduler.cpp

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "src/detail/epoll/scheduler.hpp"
1515
#include "src/detail/epoll/op.hpp"
16+
#include "src/detail/make_err.hpp"
1617

1718
#include <boost/corosio/detail/except.hpp>
1819
#include <boost/capy/core/thread_local_ptr.hpp>
@@ -73,18 +74,14 @@ epoll_scheduler(
7374
{
7475
epoll_fd_ = ::epoll_create1(EPOLL_CLOEXEC);
7576
if (epoll_fd_ < 0)
76-
detail::throw_system_error(
77-
system::error_code(errno, system::system_category()),
78-
"epoll_create1");
77+
detail::throw_system_error(make_err(errno), "epoll_create1");
7978

8079
event_fd_ = ::eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
8180
if (event_fd_ < 0)
8281
{
83-
int err = errno;
82+
int errn = errno;
8483
::close(epoll_fd_);
85-
detail::throw_system_error(
86-
system::error_code(err, system::system_category()),
87-
"eventfd");
84+
detail::throw_system_error(make_err(errn), "eventfd");
8885
}
8986

9087
// data.ptr = nullptr distinguishes wakeup events from I/O completions
@@ -93,12 +90,10 @@ epoll_scheduler(
9390
ev.data.ptr = nullptr;
9491
if (::epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, event_fd_, &ev) < 0)
9592
{
96-
int err = errno;
93+
int errn = errno;
9794
::close(event_fd_);
9895
::close(epoll_fd_);
99-
detail::throw_system_error(
100-
system::error_code(err, system::system_category()),
101-
"epoll_ctl");
96+
detail::throw_system_error(make_err(errn), "epoll_ctl");
10297
}
10398

10499
timer_svc_ = &get_timer_service(ctx, *this);
@@ -344,11 +339,7 @@ register_fd(int fd, epoll_op* op, std::uint32_t events) const
344339
ev.events = events;
345340
ev.data.ptr = op;
346341
if (::epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &ev) < 0)
347-
{
348-
detail::throw_system_error(
349-
system::error_code(errno, system::system_category()),
350-
"epoll_ctl ADD");
351-
}
342+
detail::throw_system_error(make_err(errno), "epoll_ctl ADD");
352343
}
353344

354345
void
@@ -359,11 +350,7 @@ modify_fd(int fd, epoll_op* op, std::uint32_t events) const
359350
ev.events = events;
360351
ev.data.ptr = op;
361352
if (::epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, fd, &ev) < 0)
362-
{
363-
detail::throw_system_error(
364-
system::error_code(errno, system::system_category()),
365-
"epoll_ctl MOD");
366-
}
353+
detail::throw_system_error(make_err(errno), "epoll_ctl MOD");
367354
}
368355

369356
void
@@ -477,9 +464,7 @@ do_one(long timeout_us)
477464
continue;
478465
return 0;
479466
}
480-
detail::throw_system_error(
481-
system::error_code(errno, system::system_category()),
482-
"epoll_wait");
467+
detail::throw_system_error(make_err(errno), "epoll_wait");
483468
}
484469

485470
// May dispatch timer handlers inline
@@ -502,13 +487,13 @@ do_one(long timeout_us)
502487

503488
if (events[i].events & (EPOLLERR | EPOLLHUP))
504489
{
505-
int err = 0;
506-
socklen_t len = sizeof(err);
507-
if (::getsockopt(op->fd, SOL_SOCKET, SO_ERROR, &err, &len) < 0)
508-
err = errno;
509-
if (err == 0)
510-
err = EIO;
511-
op->complete(err, 0);
490+
int errn = 0;
491+
socklen_t len = sizeof(errn);
492+
if (::getsockopt(op->fd, SOL_SOCKET, SO_ERROR, &errn, &len) < 0)
493+
errn = errno;
494+
if (errn == 0)
495+
errn = EIO;
496+
op->complete(errn, 0);
512497
}
513498
else
514499
{

src/corosio/src/detail/epoll/sockets.hpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "src/detail/epoll/op.hpp"
2626
#include "src/detail/epoll/scheduler.hpp"
2727
#include "src/detail/endpoint_convert.hpp"
28+
#include "src/detail/make_err.hpp"
2829

2930
#include <mutex>
3031

@@ -575,7 +576,7 @@ open_socket(epoll_socket_impl& impl)
575576

576577
int fd = ::socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
577578
if (fd < 0)
578-
return system::error_code(errno, system::system_category());
579+
return make_err(errno);
579580

580581
impl.fd_ = fd;
581582
return {};
@@ -618,24 +619,24 @@ open_acceptor(
618619

619620
int fd = ::socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
620621
if (fd < 0)
621-
return system::error_code(errno, system::system_category());
622+
return make_err(errno);
622623

623624
int reuse = 1;
624625
::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
625626

626627
sockaddr_in addr = detail::to_sockaddr_in(ep);
627628
if (::bind(fd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0)
628629
{
629-
int err = errno;
630+
int errn = errno;
630631
::close(fd);
631-
return system::error_code(err, system::system_category());
632+
return make_err(errn);
632633
}
633634

634635
if (::listen(fd, backlog) < 0)
635636
{
636-
int err = errno;
637+
int errn = errno;
637638
::close(fd);
638-
return system::error_code(err, system::system_category());
639+
return make_err(errn);
639640
}
640641

641642
impl.fd_ = fd;

src/corosio/src/detail/iocp/completion_key.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,14 @@ struct completion_key
4343
4444
@param sched The scheduler dequeuing the completion.
4545
@param bytes Bytes transferred (from GQCS).
46-
@param error Error code (from GetLastError if GQCS failed).
46+
@param dwError Error code (from GetLastError if GQCS failed).
4747
@param overlapped The OVERLAPPED pointer (may be nullptr for signals).
4848
@return Action for the run loop to take.
4949
*/
5050
virtual result on_completion(
5151
win_scheduler& sched,
5252
DWORD bytes,
53-
DWORD error,
53+
DWORD dwError,
5454
LPOVERLAPPED overlapped) = 0;
5555

5656
/** Destroy a completion during shutdown without invoking handler.

src/corosio/src/detail/iocp/overlapped_op.hpp

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <boost/capy/error.hpp>
2222
#include <boost/system/error_code.hpp>
2323

24+
#include "src/detail/make_err.hpp"
2425
#include "src/detail/scheduler_op.hpp"
2526

2627
#include <atomic>
@@ -52,7 +53,7 @@ struct overlapped_op
5253
capy::any_executor_ref d;
5354
system::error_code* ec_out = nullptr;
5455
std::size_t* bytes_out = nullptr;
55-
DWORD error = 0;
56+
DWORD dwError = 0;
5657
DWORD bytes_transferred = 0;
5758
bool empty_buffer = false; // True if operation was with empty buffer
5859
std::atomic<bool> cancelled{false};
@@ -75,7 +76,7 @@ struct overlapped_op
7576
Offset = 0;
7677
OffsetHigh = 0;
7778
hEvent = nullptr;
78-
error = 0;
79+
dwError = 0;
7980
bytes_transferred = 0;
8081
empty_buffer = false;
8182
cancelled.store(false, std::memory_order_relaxed);
@@ -93,15 +94,9 @@ struct overlapped_op
9394
// Explicit cancellation via cancel() or stop_token
9495
*ec_out = capy::error::canceled;
9596
}
96-
else if (error == ERROR_OPERATION_ABORTED)
97+
else if (dwError != 0)
9798
{
98-
// CancelIoEx or socket close caused abort
99-
*ec_out = capy::error::canceled;
100-
}
101-
else if (error != 0)
102-
{
103-
*ec_out = system::error_code(
104-
static_cast<int>(error), system::system_category());
99+
*ec_out = make_err(dwError);
105100
}
106101
else if (is_read_operation() && bytes_transferred == 0 && !empty_buffer)
107102
{
@@ -147,7 +142,7 @@ struct overlapped_op
147142
void complete(DWORD bytes, DWORD err) noexcept
148143
{
149144
bytes_transferred = bytes;
150-
error = err;
145+
dwError = err;
151146
}
152147
};
153148

src/corosio/src/detail/iocp/resolver_service.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "src/detail/iocp/resolver_service.hpp"
1515
#include "src/detail/iocp/scheduler.hpp"
1616
#include "src/detail/endpoint_convert.hpp"
17+
#include "src/detail/make_err.hpp"
1718

1819
#include <boost/url/ipv4_address.hpp>
1920
#include <boost/url/ipv6_address.hpp>
@@ -114,12 +115,12 @@ convert_results(
114115
void CALLBACK
115116
resolve_op::
116117
completion(
117-
DWORD error,
118+
DWORD dwError,
118119
DWORD /*bytes*/,
119120
OVERLAPPED* ov)
120121
{
121122
auto* op = static_cast<resolve_op*>(ov);
122-
op->error = error;
123+
op->dwError = dwError;
123124
op->impl->svc_.work_finished();
124125
op->impl->svc_.post(op);
125126
}
@@ -133,13 +134,12 @@ operator()()
133134
if (ec_out)
134135
{
135136
if (cancelled.load(std::memory_order_acquire))
136-
*ec_out = make_error_code(system::errc::operation_canceled);
137-
else if (error != 0)
138-
*ec_out = system::error_code(
139-
static_cast<int>(error), system::system_category());
137+
*ec_out = capy::error::canceled;
138+
else if (dwError != 0)
139+
*ec_out = make_err(dwError);
140140
}
141141

142-
if (out && !cancelled.load(std::memory_order_acquire) && error == 0 && results)
142+
if (out && !cancelled.load(std::memory_order_acquire) && dwError == 0 && results)
143143
{
144144
*out = convert_results(results, host, service);
145145
}
@@ -239,11 +239,11 @@ resolve(
239239
if (result == 0)
240240
{
241241
// Completed synchronously
242-
op.error = 0;
242+
op.dwError = 0;
243243
}
244244
else
245245
{
246-
op.error = static_cast<DWORD>(::WSAGetLastError());
246+
op.dwError = static_cast<DWORD>(::WSAGetLastError());
247247
}
248248

249249
svc_.post(&op);

src/corosio/src/detail/iocp/resolver_service.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ struct resolve_op : overlapped_op
6161

6262
/** Completion callback for GetAddrInfoExW. */
6363
static void CALLBACK completion(
64-
DWORD error,
64+
DWORD dwError,
6565
DWORD bytes,
6666
OVERLAPPED* ov);
6767

0 commit comments

Comments
 (0)