Skip to content

Commit 0df5246

Browse files
authored
Optimize server code (#5456)
* optimize code * optimize code [2] * Optimize sendfile * added enable_asan option
1 parent e692bad commit 0df5246

File tree

14 files changed

+59
-39
lines changed

14 files changed

+59
-39
lines changed

.github/WORKFLOW-PARAMETERS.md

+3
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@ Setting this parameter will cause the test program to be run with `valgrind`.
1212
```shell
1313
git commit -m "commit message --filter=[core][unit] --valgrind"
1414
```
15+
16+
## --asan
17+
Setting this parameter will cause the test program to be run with `ASAN`.

.github/workflows/core.yml

+5
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ jobs:
4343
sudo apt install -y valgrind
4444
cd core-tests && SWOOLE_VALGRIND=1 ./run.sh
4545
46+
- name: make test with asan
47+
if: "contains(github.event.head_commit.message, '--asan')"
48+
run: |
49+
cd core-tests && SWOOLE_ENABLE_ASAN=1 ./run.sh
50+
4651
- name: make test
4752
run:
4853
cd core-tests && ./run.sh

CMakeLists.txt

+5
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ if (DEFINED enable_trace_log)
100100
add_definitions(-DSW_LOG_TRACE_OPEN)
101101
endif()
102102

103+
if (DEFINED enable_asan)
104+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
105+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
106+
endif()
107+
103108
execute_process(COMMAND php-config --includes OUTPUT_VARIABLE PHP_INCLUDES OUTPUT_STRIP_TRAILING_WHITESPACE)
104109
execute_process(COMMAND php-config --extension-dir OUTPUT_VARIABLE PHP_EXTENSION_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)
105110
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PHP_INCLUDES}")

core-tests/CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ if (DEFINED enable_asan)
6161
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
6262
endif()
6363

64+
if (DEFINED enable_thread)
65+
add_definitions(-DSW_THREAD)
66+
endif()
67+
6468
# should execute before the add_executable command
6569
link_directories(${core_tests_link_directories})
6670

core-tests/run.sh

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
#!/bin/bash
2-
cmake . -DSW_THREAD=1
2+
if [ "${SWOOLE_ENABLE_ASAN}" = 1 ]; then
3+
cmake . -D enable_thread=1 -D enable_asan=1
4+
else
5+
cmake . -D enable_thread=1
6+
fi
37
make -j8
48
ipcs -q
59

core-tests/src/memory/buffer.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ TEST(buffer, append_iov) {
6363

6464
while (!buf_for_offset.empty()) {
6565
auto chunk = buf_for_offset.front();
66-
str.append(chunk->value.ptr, chunk->length);
66+
str.append(chunk->value.str, chunk->length);
6767
buf_for_offset.pop();
6868
}
6969

include/swoole_buffer.h

+4-6
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,10 @@ struct BufferChunk {
3232
uint32_t length = 0;
3333
uint32_t offset = 0;
3434
union {
35-
char *ptr;
36-
void *object;
37-
struct {
38-
uint32_t val1;
39-
uint32_t val2;
40-
} data;
35+
char *str;
36+
void *ptr;
37+
uint32_t u32;
38+
uint64_t u64;
4139
} value{};
4240
uint32_t size = 0;
4341

include/swoole_server.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -934,7 +934,10 @@ class Server {
934934
*/
935935
std::function<int(Server *, EventData *)> onTask;
936936
std::function<int(Server *, EventData *)> onFinish;
937-
937+
/**
938+
* for MessageBus
939+
*/
940+
std::function<uint64_t(void)> msg_id_generator;
938941
/**
939942
* Hook
940943
*/

src/memory/buffer.cc

+4-4
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ namespace swoole {
2121

2222
BufferChunk::BufferChunk(Type type, uint32_t size) : type(type), size(size) {
2323
if (type == TYPE_DATA && size > 0) {
24-
value.ptr = new char[size];
24+
value.str = new char[size];
2525
}
2626
}
2727

2828
BufferChunk::~BufferChunk() {
2929
if (type == TYPE_DATA) {
30-
delete[] value.ptr;
30+
delete[] value.str;
3131
}
3232
if (destroy) {
3333
destroy(this);
@@ -72,7 +72,7 @@ void Buffer::append(const void *data, uint32_t size) {
7272

7373
total_length += _n;
7474

75-
memcpy(chunk->value.ptr, _pos, _n);
75+
memcpy(chunk->value.str, _pos, _n);
7676
chunk->length = _n;
7777

7878
swoole_trace_log(SW_TRACE_BUFFER, "chunk_n=%lu|size=%u|chunk_len=%u|chunk=%p", count(), _n, chunk->length, chunk);
@@ -121,7 +121,7 @@ void Buffer::append(const struct iovec *iov, size_t iovcnt, off_t offset) {
121121
}
122122

123123
size_t _n = std::min(iov_remain_len, chunk_remain_len);
124-
memcpy(chunk->value.ptr + chunk->length, pos, _n);
124+
memcpy(chunk->value.str + chunk->length, pos, _n);
125125
total_length += _n;
126126
_length -= _n;
127127

src/network/socket.cc

+4-4
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ int Socket::handle_sendfile() {
549549
int ret;
550550
Buffer *buffer = out_buffer;
551551
BufferChunk *chunk = buffer->front();
552-
SendfileRequest *task = (SendfileRequest *) chunk->value.object;
552+
SendfileRequest *task = (SendfileRequest *) chunk->value.ptr;
553553

554554
if (task->offset == 0) {
555555
cork();
@@ -613,7 +613,7 @@ int Socket::handle_send() {
613613
return SW_OK;
614614
}
615615

616-
ssize_t ret = send(chunk->value.ptr + chunk->offset, sendn, 0);
616+
ssize_t ret = send(chunk->value.str + chunk->offset, sendn, 0);
617617
if (ret < 0) {
618618
switch (catch_write_error(errno)) {
619619
case SW_ERROR:
@@ -645,7 +645,7 @@ int Socket::handle_send() {
645645
}
646646

647647
static void Socket_sendfile_destructor(BufferChunk *chunk) {
648-
SendfileRequest *task = (SendfileRequest *) chunk->value.object;
648+
SendfileRequest *task = (SendfileRequest *) chunk->value.ptr;
649649
delete task;
650650
}
651651

@@ -685,7 +685,7 @@ int Socket::sendfile(const char *filename, off_t offset, size_t length) {
685685
}
686686

687687
BufferChunk *chunk = out_buffer->alloc(BufferChunk::TYPE_SENDFILE, 0);
688-
chunk->value.object = task.release();
688+
chunk->value.ptr = task.release();
689689
chunk->destroy = Socket_sendfile_destructor;
690690

691691
return SW_OK;

src/server/base.cc

+5-5
Original file line numberDiff line numberDiff line change
@@ -183,18 +183,18 @@ bool BaseFactory::end(SessionId session_id, int flags) {
183183
conn->closing = 0;
184184
conn->closed = 1;
185185
conn->close_errno = 0;
186+
network::Socket *_socket = conn->socket;
186187

187-
if (conn->socket == nullptr) {
188+
if (_socket == nullptr) {
188189
swoole_warning("session#%ld->socket is nullptr", session_id);
189190
return false;
190191
}
191192

192-
if (Buffer::empty(conn->socket->out_buffer) || (conn->close_reset || conn->peer_closed || conn->close_force)) {
193+
if (Buffer::empty(_socket->out_buffer) || (conn->close_reset || conn->peer_closed || conn->close_force)) {
193194
Reactor *reactor = SwooleTG.reactor;
194-
return Server::close_connection(reactor, conn->socket) == SW_OK;
195+
return Server::close_connection(reactor, _socket) == SW_OK;
195196
} else {
196-
BufferChunk *chunk = conn->socket->out_buffer->alloc(BufferChunk::TYPE_CLOSE, 0);
197-
chunk->value.data.val1 = _send.info.type;
197+
_socket->out_buffer->alloc(BufferChunk::TYPE_CLOSE, 0);
198198
conn->close_queued = 1;
199199
return true;
200200
}

src/server/master.cc

+3-4
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,8 @@ Server::Server(enum Mode _mode) {
728728
gs->pipe_packet_msg_id = 1;
729729
gs->max_concurrency = UINT_MAX;
730730

731-
message_bus.set_id_generator([this]() { return sw_atomic_fetch_add(&gs->pipe_packet_msg_id, 1); });
731+
msg_id_generator = [this]() { return sw_atomic_fetch_add(&gs->pipe_packet_msg_id, 1); };
732+
message_bus.set_id_generator(msg_id_generator);
732733
worker_thread_start = [](const WorkerFn &fn) { fn(); };
733734

734735
g_server_instance = this;
@@ -1448,11 +1449,9 @@ int Server::send_to_connection(SendData *_send) {
14481449
}
14491450
}
14501451

1451-
BufferChunk *chunk;
14521452
// close connection
14531453
if (_send->info.type == SW_SERVER_EVENT_CLOSE) {
1454-
chunk = _socket->out_buffer->alloc(BufferChunk::TYPE_CLOSE, 0);
1455-
chunk->value.data.val1 = _send->info.type;
1454+
_socket->out_buffer->alloc(BufferChunk::TYPE_CLOSE, 0);
14561455
conn->close_queued = 1;
14571456
}
14581457
// sendfile to client

src/server/reactor_thread.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ static int ReactorThread_onPipeWrite(Reactor *reactor, Event *ev) {
433433

434434
while (!Buffer::empty(buffer)) {
435435
BufferChunk *chunk = buffer->front();
436-
EventData *send_data = (EventData *) chunk->value.ptr;
436+
EventData *send_data = (EventData *) chunk->value.str;
437437

438438
// server actively closed connection, should discard the data
439439
if (Server::is_stream_event(send_data->info.type)) {
@@ -460,7 +460,7 @@ static int ReactorThread_onPipeWrite(Reactor *reactor, Event *ev) {
460460
}
461461
}
462462

463-
ret = ev->socket->send(chunk->value.ptr, chunk->length, 0);
463+
ret = ev->socket->send(chunk->value.str, chunk->length, 0);
464464
if (ret < 0) {
465465
return (ev->socket->catch_write_error(errno) == SW_WAIT) ? SW_OK : SW_ERR;
466466
} else {
@@ -767,7 +767,7 @@ int ReactorThread::init(Server *serv, Reactor *reactor, uint16_t reactor_id) {
767767
pipe_command->buffer_size = UINT_MAX;
768768
}
769769

770-
message_bus.set_id_generator([serv]() { return sw_atomic_fetch_add(&serv->gs->pipe_packet_msg_id, 1); });
770+
message_bus.set_id_generator(serv->msg_id_generator);
771771
message_bus.set_buffer_size(serv->ipc_max_size);
772772
message_bus.set_always_chunked_transfer();
773773
if (!message_bus.alloc_buffer()) {

src/server/thread.cc

+9-10
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ void Server::destroy_thread_factory() {
3838
}
3939

4040
ThreadFactory::ThreadFactory(Server *server) : BaseFactory(server) {
41-
threads_.resize(server_->task_worker_num + server_->worker_num + server_->get_user_worker_num() + 1);
41+
threads_.resize(server_->get_all_worker_num() + 1);
4242
}
4343

4444
bool ThreadFactory::start() {
@@ -77,9 +77,8 @@ void ThreadFactory::at_thread_exit(Worker *worker) {
7777

7878
void ThreadFactory::create_message_bus() {
7979
auto mb = new MessageBus();
80-
auto server = server_;
81-
mb->set_id_generator([server]() { return sw_atomic_fetch_add(&server->gs->pipe_packet_msg_id, 1); });
82-
mb->set_buffer_size(server->ipc_max_size);
80+
mb->set_id_generator(server_->msg_id_generator);
81+
mb->set_buffer_size(server_->ipc_max_size);
8382
mb->set_always_chunked_transfer();
8483
if (!mb->alloc_buffer()) {
8584
throw std::bad_alloc();
@@ -209,15 +208,12 @@ void ThreadFactory::wait() {
209208
}
210209

211210
int Server::start_worker_threads() {
212-
/**
213-
* heartbeat thread
214-
*/
211+
ThreadFactory *_factory = dynamic_cast<ThreadFactory *>(factory);
212+
215213
if (heartbeat_check_interval > 0) {
216214
start_heartbeat_thread();
217215
}
218216

219-
ThreadFactory *_factory = dynamic_cast<ThreadFactory *>(factory);
220-
221217
if (task_worker_num > 0) {
222218
SW_LOOP_N(task_worker_num) {
223219
_factory->spawn_task_worker(worker_num + i);
@@ -234,12 +230,13 @@ int Server::start_worker_threads() {
234230
}
235231
}
236232

237-
int manager_thread_id = task_worker_num + worker_num + get_user_worker_num();
233+
int manager_thread_id = get_all_worker_num();
238234
_factory->spawn_manager_thread(manager_thread_id);
239235

240236
if (swoole_event_init(0) < 0) {
241237
return SW_ERR;
242238
}
239+
243240
Reactor *reactor = sw_reactor();
244241
for (auto iter = ports.begin(); iter != ports.end(); iter++) {
245242
auto port = *iter;
@@ -252,8 +249,10 @@ int Server::start_worker_threads() {
252249
}
253250
reactor->add(port->socket, SW_EVENT_READ);
254251
}
252+
255253
SwooleTG.id = reactor->id = manager_thread_id + 1;
256254
store_listen_socket();
255+
257256
return start_master_thread(reactor);
258257
}
259258

0 commit comments

Comments
 (0)