From 52c84d144d3b07966d9b3bab8694eb012eef69ce Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 Oct 2012 11:00:01 +0200 Subject: MDEV-3802: Millisecond timeout support in non-blocking client library + fix incorrect blocking. After the merge of VIO stuff from MySQL 5.6, there were some bugs left in the non-blocking client library: - vio_io_wait() was introduced without any support for non-blocking operation, so async queries could turn into sync. - Timeouts were changed to milliseconds, but this was not reflected in the non-blocking API, also semantics was changed so signed -1 was used for "no timeout" rather than unsigned 0. Fix by implementing and using my_io_wait_async() in the non-blocking case. And by introducing a new mysql_get_timeout_value_ms() API function that provides the timeout with millisecond granularity. The old mysql_get_timeout_value() is kept and fixed to work correctly, converting the timeout to whole seconds. --- vio/viosocket.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'vio/viosocket.c') diff --git a/vio/viosocket.c b/vio/viosocket.c index f7ab95d3e6c..b13fc2d3a83 100644 --- a/vio/viosocket.c +++ b/vio/viosocket.c @@ -897,6 +897,21 @@ int vio_io_wait(Vio *vio, enum enum_vio_io_event event, int timeout) MYSQL_SOCKET_WAIT_VARIABLES(locker, state) /* no ';' */ DBUG_ENTER("vio_io_wait"); + /* + Note that if zero timeout, then we will not block, so we do not need to + yield to calling application in the async case. + */ + if (timeout != 0 && vio->async_context && vio->async_context->active) + { + MYSQL_START_SOCKET_WAIT(locker, &state, vio->mysql_socket, + PSI_SOCKET_SELECT, 0); + ret= my_io_wait_async(vio->async_context, event, timeout); + if (ret == 0) + errno= SOCKET_ETIMEDOUT; + MYSQL_END_SOCKET_WAIT(locker, 0); + DBUG_RETURN(ret); + } + memset(&pfd, 0, sizeof(pfd)); pfd.fd= sd; @@ -957,6 +972,21 @@ int vio_io_wait(Vio *vio, enum enum_vio_io_event event, int timeout) MYSQL_SOCKET_WAIT_VARIABLES(locker, state) /* no ';' */ DBUG_ENTER("vio_io_wait"); + /* + Note that if zero timeout, then we will not block, so we do not need to + yield to calling application in the async case. + */ + if (timeout != 0 && vio->async_context && vio->async_context->active) + { + MYSQL_START_SOCKET_WAIT(locker, &state, vio->mysql_socket, + PSI_SOCKET_SELECT, 0); + ret= my_io_wait_async(vio->async_context, event, timeout); + if (ret == 0) + WSASetLastError(SOCKET_ETIMEDOUT); + MYSQL_END_SOCKET_WAIT(locker, 0); + DBUG_RETURN(ret); + } + /* Convert the timeout, in milliseconds, to seconds and microseconds. */ if (timeout >= 0) { -- cgit v1.2.1