Skip to content

Commit c15595c

Browse files
committed
remove useless code
1 parent 22836ff commit c15595c

5 files changed

Lines changed: 104 additions & 43 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ echo_server
2121
.cache/
2222
.vscode/
2323
.idea/
24+
.agents/
25+
.codex/
2426
*.swp
2527
*.swo
2628
*~

server/include/io_uring.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <memory>
1010
#include <optional>
1111
#include <string>
12+
#include <string_view>
1213
#define QUEUE_DEPTH 1024
1314
namespace HTTP {
1415
class IOUring;
@@ -22,13 +23,13 @@ class IOUring {
2223
int fd;
2324
std::optional<char *> toRead;
2425
std::function<void(int)> complete;
25-
std::shared_ptr<std::string> writeData;
26+
std::string_view writeData;
2627
size_t writeOffset{0};
2728
size_t writeLen{0};
2829
};
2930
struct SqeData {
3031
std::function<void(int)> complete;
31-
std::shared_ptr<std::string> writeData;
32+
std::string_view writeData;
3233
size_t writeOffset{0};
3334
size_t writeLen{0};
3435
};
@@ -44,10 +45,10 @@ class IOUring {
4445
IOUring();
4546
IOUring &operator=(IOUring &&rhs);
4647
void Read(int fileDescriptor, std::array<char, 256> &buffer, std::function<void(int)> complete);
47-
CoFuture<size_t> ReadAsync(int fileDescriptor, std::array<char, 256> &buffer);
48-
void Write(int fileDescriptor, std::shared_ptr<std::string> data, size_t offset, size_t len,
48+
CoFuture<int> ReadAsync(int fileDescriptor, std::array<char, 256> &buffer);
49+
void Write(int fileDescriptor, std::string_view data, size_t offset, size_t len,
4950
std::function<void(int)> complete);
50-
CoFuture<size_t> WriteAsync(int fileDescriptor, std::shared_ptr<std::string> data, size_t offset,
51+
CoFuture<int> WriteAsync(int fileDescriptor, std::string_view data, size_t offset,
5152
size_t len);
5253
void Accept(int fileDescriptor, std::function<void(int)> complete);
5354
CoFuture<int> AcceptAsync(int fileDescriptor);

server/src/io_uring.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ void IOUring::AddEntries() {
3838
io_uring_prep_read(sqEntry, entry.fd, entry.toRead.value(), 256, 0);
3939
} else if (entry.type == IOUring::ACCEPT) {
4040
io_uring_prep_accept(sqEntry, entry.fd, nullptr, nullptr, 0);
41-
} else {
42-
const char *ptr = sqeData->writeData->data() + sqeData->writeOffset;
41+
} else [[likely]] {
42+
const char *ptr = sqeData->writeData.data() + sqeData->writeOffset;
4343
io_uring_prep_write(sqEntry, entry.fd, ptr, sqeData->writeLen, 0);
4444
}
4545
io_uring_sqe_set_data(sqEntry, sqeData);
@@ -73,15 +73,15 @@ void IOUring::Poll() {
7373
}
7474
}
7575

76-
void IOUring::Write(int fileDescriptor, std::shared_ptr<std::string> data, size_t offset,
76+
void IOUring::Write(int fileDescriptor, std::string_view data, size_t offset,
7777
size_t len, std::function<void(int)> complete) {
7878
if (fileDescriptor < 0) {
7979
throw std::runtime_error("Invalid file descriptor");
8080
}
8181
Entry entry;
8282
entry.type = IOUring::WRITE;
8383
entry.fd = fileDescriptor;
84-
entry.writeData = std::move(data);
84+
entry.writeData = data;
8585
entry.writeOffset = offset;
8686
entry.writeLen = len;
8787
entry.complete = std::move(complete);
@@ -102,11 +102,11 @@ void IOUring::Read(int fileDescriptor, std::array<char, 256> &buffer,
102102
queue_.push_back(entry);
103103
}
104104

105-
CoFuture<size_t> IOUring::ReadAsync(int fileDescriptor, std::array<char, 256> &buffer) {
106-
auto promise = std::make_shared<CoPromise<size_t>>();
105+
CoFuture<int> IOUring::ReadAsync(int fileDescriptor, std::array<char, 256> &buffer) {
106+
auto promise = std::make_shared<CoPromise<int>>();
107107
auto future = promise->GetFuture();
108108
Read(fileDescriptor, buffer, [promise](int result) {
109-
promise->Set(result < 0 ? 0 : static_cast<size_t>(result));
109+
promise->Set(result);
110110
});
111111
return future;
112112
}
@@ -132,12 +132,12 @@ CoFuture<int> IOUring::AcceptAsync(int fileDescriptor) {
132132
return future;
133133
}
134134

135-
CoFuture<size_t> IOUring::WriteAsync(int fileDescriptor, std::shared_ptr<std::string> data,
135+
CoFuture<int> IOUring::WriteAsync(int fileDescriptor, std::string_view data,
136136
size_t offset, size_t len) {
137-
auto promise = std::make_shared<CoPromise<size_t>>();
137+
auto promise = std::make_shared<CoPromise<int>>();
138138
auto future = promise->GetFuture();
139-
Write(fileDescriptor, std::move(data), offset, len, [promise](int result) {
140-
promise->Set(result < 0 ? 0 : static_cast<size_t>(result));
139+
Write(fileDescriptor, data, offset, len, [promise](int result) {
140+
promise->Set(result);
141141
});
142142
return future;
143143
}

server/src/read_iterator.cpp

Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,41 @@
11
#include "read_iterator.h"
22
#include "http_error.h"
33
#include <algorithm>
4+
#include <cerrno>
5+
#include <stdexcept>
46
#include <string>
7+
#include <system_error>
58
namespace HTTP {
9+
10+
namespace {
11+
constexpr int kMaxIoAttempts = 3;
12+
13+
bool IsRetryableIoError(int result) {
14+
return result == -EINTR || result == -EAGAIN || result == -EWOULDBLOCK;
15+
}
16+
} // namespace
17+
618
ReadIterator::ReadIterator(IOUring &ring, int fd_) : ring_(ring), fd_(fd_), length_(0), position_(0) {
719
}
820

921
CoFuture<void> ReadIterator::Ensure() {
1022
if (position_ >= length_) {
11-
length_ = co_await ring_.ReadAsync(fd_, buffer_);
23+
for (int attempt = 1; attempt <= kMaxIoAttempts; ++attempt) {
24+
int result = co_await ring_.ReadAsync(fd_, buffer_);
25+
if (result > 0) {
26+
length_ = static_cast<size_t>(result);
27+
position_ = 0;
28+
co_return;
29+
}
30+
if (result == 0) {
31+
length_ = 0;
32+
position_ = 0;
33+
co_return;
34+
}
35+
if (!IsRetryableIoError(result) || attempt == kMaxIoAttempts) {
36+
throw std::system_error(-result, std::generic_category(), "read failed");
37+
}
38+
}
1239
position_ = 0;
1340
}
1441
co_return;
@@ -187,30 +214,34 @@ CoFuture<void> ReadIterator::ParseHeaders(RequestData &data) {
187214
CoFuture<void> ReadIterator::ParseBody(RequestData &data) {
188215
auto it = data.headers.find("Content-Length");
189216
if (it != data.headers.end()) {
217+
size_t length;
190218
try {
191-
size_t length = std::stoul(it->second);
192-
data.body.clear();
193-
data.body.reserve(length);
219+
length = std::stoul(it->second);
220+
} catch (const std::invalid_argument &) {
221+
co_return;
222+
} catch (const std::out_of_range &) {
223+
co_return;
224+
}
225+
data.body.clear();
226+
data.body.reserve(length);
227+
co_await Ensure();
228+
if (*this && (**this == '\n' || **this == '\r')) {
229+
co_await ++*this;
194230
co_await Ensure();
195231
if (*this && (**this == '\n' || **this == '\r')) {
196232
co_await ++*this;
197-
co_await Ensure();
198-
if (*this && (**this == '\n' || **this == '\r')) {
199-
co_await ++*this;
200-
}
201-
}
202-
size_t remaining = length;
203-
while (remaining > 0) {
204-
co_await Ensure();
205-
if (!*this) break;
206-
size_t avail = Available();
207-
if (avail == 0) continue;
208-
size_t take = std::min(avail, remaining);
209-
data.body.append(CurrentPtr(), take);
210-
Advance(take);
211-
remaining -= take;
212233
}
213-
} catch (...) {
234+
}
235+
size_t remaining = length;
236+
while (remaining > 0) {
237+
co_await Ensure();
238+
if (!*this) break;
239+
size_t avail = Available();
240+
if (avail == 0) continue;
241+
size_t take = std::min(avail, remaining);
242+
data.body.append(CurrentPtr(), take);
243+
Advance(take);
244+
remaining -= take;
214245
}
215246
co_return;
216247
}

server/src/server.cpp

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "read_iterator.h"
44
#include "request_data.h"
55
#include "trie.h"
6+
#include <cerrno>
67
#include <cctype>
78
#include <csignal>
89
#include <iostream>
@@ -11,6 +12,7 @@
1112
#include <optional>
1213
#include <sstream>
1314
#include <stdexcept>
15+
#include <system_error>
1416
#include <sys/socket.h>
1517
#include <thread>
1618
#include <unistd.h>
@@ -62,6 +64,12 @@ static bool wants_close(const RequestData &request) {
6264
ch = static_cast<char>(std::tolower(static_cast<unsigned char>(ch)));
6365
return value.find("close") != std::string::npos;
6466
}
67+
68+
constexpr int kMaxIoAttempts = 3;
69+
70+
bool IsRetryableIoError(int result) {
71+
return result == -EINTR || result == -EAGAIN || result == -EWOULDBLOCK;
72+
}
6573
} // namespace
6674

6775
Server::Server(Server &&rhs) {
@@ -136,15 +144,24 @@ CoFuture<void> Server::WriteResponse(IOUring &ring, int connectionFD, const Resp
136144
}
137145
text << "\r\n";
138146
text << data.body;
139-
auto final = std::make_shared<std::string>(text.str());
147+
std::string final = text.str();
140148
size_t sent = 0;
141-
while (sent < final->size()) {
142-
size_t wrote = co_await ring.WriteAsync(connectionFD, final, sent,
143-
final->size() - sent);
144-
if (wrote == 0) {
149+
int attempts = 0;
150+
while (sent < final.size()) {
151+
int result = co_await ring.WriteAsync(connectionFD, final, sent,
152+
final.size() - sent);
153+
if (result > 0) {
154+
sent += static_cast<size_t>(result);
155+
attempts = 0;
156+
continue;
157+
}
158+
if (result == 0) {
145159
break;
146160
}
147-
sent += wrote;
161+
++attempts;
162+
if (!IsRetryableIoError(result) || attempts >= kMaxIoAttempts) {
163+
throw std::system_error(-result, std::generic_category(), "write failed");
164+
}
148165
}
149166
co_return;
150167
}
@@ -198,6 +215,11 @@ CoFuture<void> Server::Process(IOUring &ring, int connectionFD) {
198215
response.body = error.message;
199216
mustClose = true;
200217
keepAlive = false;
218+
} catch (const std::system_error &) {
219+
response.status = 500;
220+
response.body = "Internal server error";
221+
mustClose = true;
222+
keepAlive = false;
201223
} catch (std::runtime_error &error) {
202224
response.status = 500;
203225
response.body = error.what();
@@ -211,7 +233,12 @@ CoFuture<void> Server::Process(IOUring &ring, int connectionFD) {
211233
}
212234

213235
if (!mustClose || response.status != 400 || !response.body.empty()) {
214-
co_await WriteResponse(ring, connectionFD, response, keepAlive);
236+
try {
237+
co_await WriteResponse(ring, connectionFD, response, keepAlive);
238+
} catch (const std::system_error &) {
239+
mustClose = true;
240+
keepAlive = false;
241+
}
215242
}
216243
if (!keepAlive || mustClose) {
217244
(void)shutdown(connectionFD, SHUT_WR);

0 commit comments

Comments
 (0)