Skip to content

Commit e5b1c90

Browse files
committed
Optimize the details of iouring, Fix core tests
1 parent b0b32c4 commit e5b1c90

File tree

9 files changed

+90
-68
lines changed

9 files changed

+90
-68
lines changed

core-tests/src/coroutine/async.cpp

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
#include "test_coroutine.h"
2-
#ifdef HAVE_SWOOLE_DIR
32
#include "swoole_async.h"
4-
#else
5-
#include "swoole/swoole_async.h"
6-
#endif
3+
74
#include <iostream>
85
#include <regex>
96

@@ -57,7 +54,7 @@ TEST(coroutine_async, error) {
5754
coroutine::run([](void *arg) {
5855
int retval = 0x7009501;
5956
const char *test_file = "/tmp/swoole_core_test_file_not_exists";
60-
swoole::coroutine::async([&](void) { retval = open(test_file, O_RDONLY); }, -1);
57+
swoole::coroutine::async([&](void) { retval = open(test_file, O_RDONLY); });
6158
ASSERT_EQ(retval, -1);
6259
ASSERT_EQ(errno, ENOENT);
6360
});

examples/runtime/file.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
Swoole\Runtime::enableCoroutine();
3-
go(function() {
4-
$fp = fopen('data.txt', 'w');
3+
Co\run(function() {
4+
$fp = fopen('data.txt', 'w+');
55
echo "open\n";
66
fwrite($fp, str_repeat('A', 1024));
77
fwrite($fp, str_repeat('B', 1024));

ext-src/swoole_socket_coro.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -1569,7 +1569,7 @@ static void socket_coro_write_vector(INTERNAL_FUNCTION_PARAMETERS, const bool al
15691569
iovcnt = zend_array_count(vht);
15701570

15711571
if (iovcnt > IOV_MAX) {
1572-
sw_tg_buffer()->length = sw_snprintf(sw_tg_buffer()->str, sw_tg_buffer()->size, IOV_MAX_ERROR_MSG, IOV_MAX);
1572+
sw_tg_buffer()->length = sw_snprintf(sw_tg_buffer()->str, sw_tg_buffer()->size, SW_IOV_MAX_ERROR_MSG, IOV_MAX);
15731573
sock->socket->set_err(EINVAL, sw_tg_buffer()->to_std_string());
15741574
RETURN_FALSE;
15751575
}
@@ -1639,7 +1639,7 @@ static void socket_coro_read_vector(INTERNAL_FUNCTION_PARAMETERS, const bool all
16391639
iovcnt = zend_array_count(vht);
16401640

16411641
if (iovcnt > IOV_MAX) {
1642-
sw_tg_buffer()->length = sw_snprintf(sw_tg_buffer()->str, sw_tg_buffer()->size, IOV_MAX_ERROR_MSG, IOV_MAX);
1642+
sw_tg_buffer()->length = sw_snprintf(sw_tg_buffer()->str, sw_tg_buffer()->size, SW_IOV_MAX_ERROR_MSG, IOV_MAX);
16431643
sock->socket->set_err(EINVAL, sw_tg_buffer()->to_std_string());
16441644
RETURN_FALSE;
16451645
}

ext-src/swoole_thread.cc

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <sys/resource.h>
2424

2525
#include <unordered_map>
26+
#include <atomic>
2627

2728
#include "swoole_thread.h"
2829

include/swoole_client.h

+15-6
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,12 @@ class Client {
103103
std::shared_ptr<SSLContext> ssl_context = nullptr;
104104
#endif
105105

106-
std::function<void (Client *cli)> onConnect = nullptr;
107-
std::function<void (Client *cli)> onError = nullptr;
108-
std::function<void (Client *cli, const char *, size_t)> onReceive = nullptr;
109-
std::function<void (Client *cli)> onClose = nullptr;
110-
std::function<void (Client *cli)> onBufferFull = nullptr;
111-
std::function<void (Client *cli)> onBufferEmpty = nullptr;
106+
std::function<void(Client *cli)> onConnect = nullptr;
107+
std::function<void(Client *cli)> onError = nullptr;
108+
std::function<void(Client *cli, const char *, size_t)> onReceive = nullptr;
109+
std::function<void(Client *cli)> onClose = nullptr;
110+
std::function<void(Client *cli)> onBufferFull = nullptr;
111+
std::function<void(Client *cli)> onBufferEmpty = nullptr;
112112

113113
int (*connect)(Client *cli, const char *host, int port, double _timeout, int sock_flag) = nullptr;
114114
ssize_t (*send)(Client *cli, const char *data, size_t length, int flags) = nullptr;
@@ -133,6 +133,15 @@ class Client {
133133
return socket->socket_type;
134134
}
135135

136+
const std::string *get_http_proxy_host_name() {
137+
#ifdef SW_USE_OPENSSL
138+
if (ssl_context && !ssl_context->tls_host_name.empty()) {
139+
return &ssl_context->tls_host_name;
140+
}
141+
#endif
142+
return &http_proxy->target_host;
143+
}
144+
136145
int sleep();
137146
int wakeup();
138147
int shutdown(int __how);

include/swoole_config.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,9 @@
161161
#define IOV_MAX 16
162162
#endif
163163

164-
#define IOV_MAX_ERROR_MSG "The maximum of iov count is %d"
164+
#define SW_IOV_MAX_ERROR_MSG "The maximum of iov count is %d"
165+
166+
#define SW_IOURING_CQES_SIZE 8192
165167

166168
/**
167169
* HTTP Protocol

scripts/make.sh

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ COMPILE_PARAMS="--enable-openssl \
99
--enable-swoole-curl \
1010
--enable-cares \
1111
--enable-swoole-pgsql \
12-
--enable-iouring \
1312
--with-swoole-odbc=unixODBC,/usr \
1413
--enable-swoole-sqlite"
1514

src/coroutine/iouring.cc

+56-24
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ Iouring::Iouring(Reactor *_reactor) {
8080
}
8181

8282
if (SwooleG.iouring_workers > 0) {
83-
unsigned int workers[2] = {SwooleG.iouring_workers, SwooleG.iouring_workers};
83+
uint32_t workers[2] = {SwooleG.iouring_workers, SwooleG.iouring_workers};
8484
ret = io_uring_register_iowq_max_workers(&ring, workers);
8585

8686
if (ret < 0) {
@@ -93,6 +93,7 @@ Iouring::Iouring(Reactor *_reactor) {
9393
}
9494

9595
ring_socket = make_socket(ring.ring_fd, SW_FD_IOURING);
96+
ring_socket->object = this;
9697

9798
reactor->set_exit_condition(Reactor::EXIT_CONDITION_IOURING, [](Reactor *reactor, size_t &event_num) -> bool {
9899
if (SwooleTG.iouring && SwooleTG.iouring->get_task_num() == 0 && SwooleTG.iouring->is_empty_waiting_tasks()) {
@@ -113,14 +114,16 @@ Iouring::Iouring(Reactor *_reactor) {
113114
}
114115

115116
Iouring::~Iouring() {
116-
if (ring_socket) {
117-
if (!ring_socket->removed) {
118-
reactor->del(ring_socket);
119-
}
120-
ring_socket->move_fd();
121-
ring_socket->free();
122-
ring_socket = nullptr;
117+
if (!ring_socket) {
118+
return;
119+
}
120+
121+
if (!ring_socket->removed) {
122+
reactor->del(ring_socket);
123123
}
124+
ring_socket->move_fd();
125+
ring_socket->free();
126+
ring_socket = nullptr;
124127

125128
io_uring_queue_exit(&ring);
126129
}
@@ -130,24 +133,18 @@ bool Iouring::ready() {
130133
}
131134

132135
bool Iouring::wakeup() {
133-
unsigned count = 0;
134-
unsigned num = 8192;
135-
void *data = nullptr;
136-
IouringEvent *event = nullptr;
137136
IouringEvent *waiting_task = nullptr;
138-
struct io_uring_cqe *cqe = nullptr;
139-
struct io_uring_cqe *cqes[num];
137+
struct io_uring_cqe *cqes[SW_IOURING_CQES_SIZE];
140138

141139
while (true) {
142-
count = io_uring_peek_batch_cqe(&ring, cqes, num);
140+
auto count = io_uring_peek_batch_cqe(&ring, cqes, SW_IOURING_CQES_SIZE);
143141
if (count == 0) {
144142
return true;
145143
}
146144

147-
for (unsigned i = 0; i < count; i++) {
148-
cqe = cqes[i];
149-
data = io_uring_cqe_get_data(cqe);
150-
event = static_cast<IouringEvent *>(data);
145+
for (decltype(count) i = 0; i < count; i++) {
146+
struct io_uring_cqe *cqe = cqes[i];
147+
IouringEvent *task = static_cast<IouringEvent *>(io_uring_cqe_get_data(cqe));
151148
task_num--;
152149
if (cqe->res < 0) {
153150
errno = -(cqe->res);
@@ -158,15 +155,15 @@ bool Iouring::wakeup() {
158155
*/
159156
if (cqe->res == -EAGAIN) {
160157
io_uring_cq_advance(&ring, 1);
161-
waiting_tasks.push(event);
158+
waiting_tasks.push(task);
162159
continue;
163160
}
164161
}
165162

166-
event->result = (cqe->res >= 0 ? cqe->res : -1);
163+
task->result = (cqe->res >= 0 ? cqe->res : -1);
167164
io_uring_cq_advance(&ring, 1);
168165

169-
event->coroutine->resume();
166+
task->coroutine->resume();
170167

171168
if (!is_empty_waiting_tasks()) {
172169
waiting_task = waiting_tasks.front();
@@ -181,7 +178,42 @@ bool Iouring::wakeup() {
181178
return true;
182179
}
183180

181+
static const char *get_opcode_name(IouringOpcode opcode) {
182+
switch (opcode) {
183+
case SW_IORING_OP_OPENAT:
184+
return "OPENAT";
185+
case SW_IORING_OP_CLOSE:
186+
return "CLOSE";
187+
case SW_IORING_OP_STATX:
188+
return "STATX";
189+
case SW_IORING_OP_READ:
190+
return "READ";
191+
case SW_IORING_OP_WRITE:
192+
return "WRITE";
193+
case SW_IORING_OP_RENAMEAT:
194+
return "RENAMEAT";
195+
case SW_IORING_OP_MKDIRAT:
196+
return "MKDIRAT";
197+
case SW_IORING_OP_FSTAT:
198+
return "FSTAT";
199+
case SW_IORING_OP_LSTAT:
200+
return "LSTAT";
201+
case SW_IORING_OP_UNLINK_FILE:
202+
return "UNLINK_FILE";
203+
case SW_IORING_OP_UNLINK_DIR:
204+
return "UNLINK_DIR";
205+
case SW_IORING_OP_FSYNC:
206+
return "FSYNC";
207+
case SW_IORING_OP_FDATASYNC:
208+
return "FDATASYNC";
209+
default:
210+
return "unknown";
211+
}
212+
}
213+
184214
bool Iouring::submit(IouringEvent *event) {
215+
swoole_trace("opcode=%s, fd=%d, path=%s", get_opcode_name(event->opcode), event->fd, event->pathname);
216+
185217
int ret = io_uring_submit(&ring);
186218

187219
if (ret < 0) {
@@ -434,8 +466,8 @@ int Iouring::stat(const char *path, struct stat *statbuf) {
434466
}
435467

436468
int Iouring::callback(Reactor *reactor, Event *event) {
437-
Iouring *iouring = SwooleTG.iouring;
438-
return iouring->wakeup() ? 1 : 0;
469+
Iouring *iouring = static_cast<Iouring *>(event->socket->object);
470+
return iouring->wakeup() ? SW_OK : SW_ERR;
439471
}
440472
} // namespace swoole
441473
#endif

src/network/client.cc

+9-27
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,6 @@ static int Client_tcp_connect_sync(Client *cli, const char *host, int port, doub
557557
if (ret >= 0) {
558558
cli->active = 1;
559559

560-
// socks5 proxy
561560
if (cli->socks5_proxy) {
562561
char buf[1024];
563562
Socks5Proxy::pack(buf, cli->socks5_proxy->username.empty() ? 0x00 : 0x02);
@@ -581,12 +580,7 @@ static int Client_tcp_connect_sync(Client *cli, const char *host, int port, doub
581580
}
582581
} else if (cli->http_proxy) {
583582
auto proxy_buf = sw_tg_buffer();
584-
const std::string *host_name = &cli->http_proxy->target_host;
585-
#ifdef SW_USE_OPENSSL
586-
if (cli->ssl_context && !cli->ssl_context->tls_host_name.empty()) {
587-
host_name = &cli->ssl_context->tls_host_name;
588-
}
589-
#endif
583+
const std::string *host_name = cli->get_http_proxy_host_name();
590584
size_t n_write = cli->http_proxy->pack(proxy_buf, host_name);
591585
if (cli->send(cli, proxy_buf->str, n_write, 0) < 0) {
592586
return SW_ERR;
@@ -919,7 +913,7 @@ static int Client_onStreamRead(Reactor *reactor, Event *event) {
919913
if (cli->http_proxy && cli->http_proxy->state != SW_HTTP_PROXY_STATE_READY) {
920914
n = event->socket->recv(buf, buf_size, 0);
921915
if (n <= 0) {
922-
_connect_fail:
916+
_connect_fail:
923917
cli->active = 0;
924918
cli->close();
925919
if (cli->onError) {
@@ -929,8 +923,7 @@ static int Client_onStreamRead(Reactor *reactor, Event *event) {
929923
}
930924
cli->buffer->length += n;
931925
if (!cli->http_proxy->handshake(cli->buffer)) {
932-
swoole_error_log(
933-
SW_LOG_NOTICE, SW_ERROR_HTTP_PROXY_HANDSHAKE_ERROR, "failed to handshake with http proxy");
926+
swoole_error_log(SW_LOG_NOTICE, SW_ERROR_HTTP_PROXY_HANDSHAKE_ERROR, "failed to handshake with http proxy");
934927
goto _connect_fail;
935928
}
936929
cli->http_proxy->state = SW_HTTP_PROXY_STATE_READY;
@@ -957,7 +950,7 @@ static int Client_onStreamRead(Reactor *reactor, Event *event) {
957950
}
958951

959952
#ifdef SW_USE_OPENSSL
960-
if (cli->open_ssl && cli->socket->ssl_state == SW_SSL_STATE_WAIT_STREAM) {
953+
if (cli->open_ssl && cli->socket->ssl_state != SW_SSL_STATE_READY) {
961954
if (cli->ssl_handshake() < 0) {
962955
goto _connect_fail;
963956
}
@@ -1132,22 +1125,11 @@ static int Client_onWrite(Reactor *reactor, Event *event) {
11321125
}
11331126
// http proxy
11341127
if (cli->http_proxy && cli->http_proxy->state == SW_HTTP_PROXY_STATE_WAIT) {
1135-
#ifdef SW_USE_OPENSSL
1136-
if (cli->open_ssl) {
1137-
cli->http_proxy->state = SW_HTTP_PROXY_STATE_HANDSHAKE;
1138-
auto proxy_buf = sw_tg_buffer();
1139-
const std::string *host_name = &cli->http_proxy->target_host;
1140-
#ifdef SW_USE_OPENSSL
1141-
if (cli->ssl_context && !cli->ssl_context->tls_host_name.empty()) {
1142-
host_name = &cli->ssl_context->tls_host_name;
1143-
}
1144-
#endif
1145-
size_t n = cli->http_proxy->pack(proxy_buf, host_name);
1146-
swoole_trace_log(SW_TRACE_HTTP_CLIENT, "proxy request: <<EOF\n%.*sEOF", (int) n, proxy_buf->str);
1147-
1148-
return cli->send(cli, proxy_buf->str, n, 0);
1149-
}
1150-
#endif
1128+
auto proxy_buf = sw_tg_buffer();
1129+
const std::string *host_name = cli->get_http_proxy_host_name();
1130+
size_t n = cli->http_proxy->pack(proxy_buf, host_name);
1131+
swoole_trace_log(SW_TRACE_HTTP_CLIENT, "proxy request: <<EOF\n%.*sEOF", (int) n, proxy_buf->str);
1132+
return cli->send(cli, proxy_buf->str, n, 0);
11511133
}
11521134
#ifdef SW_USE_OPENSSL
11531135
if (cli->open_ssl) {

0 commit comments

Comments
 (0)