Skip to content

Commit

Permalink
Fix send yield logic bug (#3397)
Browse files Browse the repository at this point in the history
* Fix send yield logic bug

* use auto

* Use auto

* Use auto 2

* defense

Co-authored-by: matyhtf <[email protected]>
  • Loading branch information
twose and matyhtf authored Jun 16, 2020
1 parent e166871 commit 3acd648
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 49 deletions.
16 changes: 8 additions & 8 deletions src/server/reactor_thread.cc
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ static int swReactorThread_onWrite(swReactor *reactor, swEvent *ev)
if (conn->close_notify)
{
#ifdef SW_USE_OPENSSL
if (conn->socket->ssl && conn->socket->ssl_state != SW_SSL_STATE_READY)
if (socket->ssl && socket->ssl_state != SW_SSL_STATE_READY)
{
return swReactorThread_close(reactor, socket);
}
Expand All @@ -765,9 +765,9 @@ static int swReactorThread_onWrite(swReactor *reactor, swEvent *ev)
return swReactorThread_close(reactor, socket);
}

while (!swBuffer_empty(conn->socket->out_buffer))
while (!swBuffer_empty(socket->out_buffer))
{
chunk = swBuffer_get_chunk(conn->socket->out_buffer);
chunk = swBuffer_get_chunk(socket->out_buffer);
if (chunk->type == SW_CHUNK_CLOSE)
{
_close_fd:
Expand All @@ -785,35 +785,35 @@ static int swReactorThread_onWrite(swReactor *reactor, swEvent *ev)

if (ret < 0)
{
if (conn->socket->close_wait)
if (socket->close_wait)
{
conn->close_errno = errno;
goto _close_fd;
}
else if (conn->socket->send_wait)
else if (socket->send_wait)
{
break;
}
}
}

if (conn->overflow && conn->socket->out_buffer->length < conn->socket->buffer_size)
if (conn->overflow && socket->out_buffer->length < socket->buffer_size)
{
conn->overflow = 0;
}

if (serv->onBufferEmpty && conn->high_watermark)
{
swListenPort *port = swServer_get_port(serv, fd);
if (conn->socket->out_buffer->length <= port->buffer_low_watermark)
if (socket->out_buffer->length <= port->buffer_low_watermark)
{
conn->high_watermark = 0;
serv->notify(serv, conn, SW_SERVER_EVENT_BUFFER_EMPTY);
}
}

//remove EPOLLOUT event
if (!conn->peer_closed && swBuffer_empty(conn->socket->out_buffer))
if (!conn->peer_closed && !socket->removed && swBuffer_empty(socket->out_buffer))
{
reactor->set(reactor, socket, SW_EVENT_READ);
}
Expand Down
66 changes: 25 additions & 41 deletions swoole_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1859,28 +1859,21 @@ void php_swoole_onClose(swServer *serv, swDataHead *info)

if (SwooleG.enable_coroutine && serv->send_yield)
{
unordered_map<int, list<php_coro_context *> *>::iterator _i_coros_list = send_coroutine_map.find(info->fd);
auto _i_coros_list = send_coroutine_map.find(info->fd);
if (_i_coros_list != send_coroutine_map.end())
{
list<php_coro_context *> *coros_list = _i_coros_list->second;
if (coros_list->empty())
auto coros_list = _i_coros_list->second;
send_coroutine_map.erase(info->fd);
while (!coros_list->empty())
{
php_swoole_fatal_error(E_WARNING, "send_yield[onClose]: nothing can be resumed");
}
else
{
do
{
php_coro_context *context = coros_list->front();
coros_list->pop_front();
swoole_set_last_error(ECONNRESET);
zval_ptr_dtor(&context->coro_params);
ZVAL_NULL(&context->coro_params);
php_swoole_server_send_resume(serv, context, info->fd);
} while (!coros_list->empty());
delete coros_list;
send_coroutine_map.erase(info->fd);
php_coro_context *context = coros_list->front();
coros_list->pop_front();
swoole_set_last_error(ECONNRESET);
zval_ptr_dtor(&context->coro_params);
ZVAL_NULL(&context->coro_params);
php_swoole_server_send_resume(serv, context, info->fd);
}
delete coros_list;
}
}

Expand Down Expand Up @@ -1929,10 +1922,10 @@ static void php_swoole_onSendTimeout(swTimer *timer, swTimer_node *tnode)

int fd = (int) (long) context->private_data;

unordered_map<int, list<php_coro_context *> *>::iterator _i_coros_list = send_coroutine_map.find(fd);
auto _i_coros_list = send_coroutine_map.find(fd);
if (_i_coros_list != send_coroutine_map.end())
{
list<php_coro_context *> *coros_list = _i_coros_list->second;
auto coros_list = _i_coros_list->second;
coros_list->remove(context);
//free memory
if (coros_list->size() == 0)
Expand Down Expand Up @@ -2018,9 +2011,9 @@ void php_swoole_server_send_yield(swServer *serv, int fd, zval *zdata, zval *ret

php_coro_context *context = (php_coro_context *) emalloc(sizeof(php_coro_context));
coros_list->push_back(context);
context->private_data = (void*) (long) fd;
if (serv->send_timeout > 0)
{
context->private_data = (void*) (long) fd;
context->timer = swoole_timer_add((long) (serv->send_timeout * 1000), SW_FALSE, php_swoole_onSendTimeout, context);
}
else
Expand Down Expand Up @@ -2088,31 +2081,22 @@ void php_swoole_onBufferEmpty(swServer *serv, swDataHead *info)

if (serv->send_yield)
{
unordered_map<int, list<php_coro_context *> *>::iterator _i_coros_list = send_coroutine_map.find(info->fd);
auto _i_coros_list = send_coroutine_map.find(info->fd);
if (_i_coros_list != send_coroutine_map.end())
{
list<php_coro_context *> *coros_list = _i_coros_list->second;
if (coros_list->empty())
auto coros_list = _i_coros_list->second;
send_coroutine_map.erase(info->fd);
while (!coros_list->empty())
{
php_swoole_fatal_error(E_WARNING, "send_yield: nothing can be resumed");
}
else
{
do
php_coro_context *context = coros_list->front();
coros_list->pop_front();
if (php_swoole_server_send_resume(serv, context, info->fd) == SW_CONTINUE)
{
php_coro_context *context = coros_list->front();
if (php_swoole_server_send_resume(serv, context, info->fd) == SW_CONTINUE)
{
return;
}
else
{
coros_list->pop_front();
}
} while (!coros_list->empty());
delete coros_list;
send_coroutine_map.erase(info->fd);
coros_list->push_back(context);
return;
}
}
delete coros_list;
}
}

Expand Down

0 comments on commit 3acd648

Please sign in to comment.