Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitff181d1

Browse files
jchampiomacdice
andcommitted
oauth: Remove stale events from the kqueue multiplexer
If a socket is added to the kqueue, becomes readable/writable, andsubsequently becomes non-readable/writable again, the kqueue itself willremain readable until either the socket registration is removed, or thestale event is cleared via a call to kevent().In many simple cases, Curl itself will remove the socket registrationquickly, but in real-world usage, this is not guaranteed to happen. Thekqueue can then remain stuck in a permanently readable state until therequest ends, which results in pointless wakeups for the client andwasted CPU time.Implement comb_multiplexer() to call kevent() and unstick any staleevents that would cause unnecessary callbacks. This is called rightafter drive_request(), before we return control to the client to wait.Suggested-by: Thomas Munro <thomas.munro@gmail.com>Co-authored-by: Thomas Munro <thomas.munro@gmail.com>Reviewed-by: Thomas Munro <thomas.munro@gmail.com>Backpatch-through: 18Discussion:https://postgr.es/m/CAOYmi+nDZxJHaWj9_jRSyf8uMToCADAmOfJEggsKW-kY7aUwHA@mail.gmail.com
1 parent4cd9d5f commitff181d1

File tree

1 file changed

+61
-6
lines changed

1 file changed

+61
-6
lines changed

‎src/interfaces/libpq-oauth/oauth-curl.c‎

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,6 +1376,53 @@ register_socket(CURL *curl, curl_socket_t socket, int what, void *ctx,
13761376
#endif
13771377
}
13781378

1379+
/*
1380+
* If there is no work to do on any of the descriptors in the multiplexer, then
1381+
* this function must ensure that the multiplexer is not readable.
1382+
*
1383+
* Unlike epoll descriptors, kqueue descriptors only transition from readable to
1384+
* unreadable when kevent() is called and finds nothing, after removing
1385+
* level-triggered conditions that have gone away. We therefore need a dummy
1386+
* kevent() call after operations might have been performed on the monitored
1387+
* sockets or timer_fd. Any event returned is ignored here, but it also remains
1388+
* queued (being level-triggered) and leaves the descriptor readable. This is a
1389+
* no-op for epoll descriptors.
1390+
*/
1391+
staticbool
1392+
comb_multiplexer(structasync_ctx*actx)
1393+
{
1394+
#if defined(HAVE_SYS_EPOLL_H)
1395+
/* The epoll implementation doesn't hold onto stale events. */
1396+
return true;
1397+
#elif defined(HAVE_SYS_EVENT_H)
1398+
structtimespectimeout= {0};
1399+
structkeventev;
1400+
1401+
/*
1402+
* Try to read a single pending event. We can actually ignore the result:
1403+
* either we found an event to process, in which case the multiplexer is
1404+
* correctly readable for that event at minimum, and it doesn't matter if
1405+
* there are any stale events; or we didn't find any, in which case the
1406+
* kernel will have discarded any stale events as it traveled to the end
1407+
* of the queue.
1408+
*
1409+
* Note that this depends on our registrations being level-triggered --
1410+
* even the timer, so we use a chained kqueue for that instead of an
1411+
* EVFILT_TIMER on the top-level mux. If we used edge-triggered events,
1412+
* this call would improperly discard them.
1413+
*/
1414+
if (kevent(actx->mux,NULL,0,&ev,1,&timeout)<0)
1415+
{
1416+
actx_error(actx,"could not comb kqueue: %m");
1417+
return false;
1418+
}
1419+
1420+
return true;
1421+
#else
1422+
#error comb_multiplexer is not implemented on this platform
1423+
#endif
1424+
}
1425+
13791426
/*
13801427
* Enables or disables the timer in the multiplexer set. The timeout value is
13811428
* in milliseconds (negative values disable the timer).
@@ -2755,13 +2802,21 @@ pg_fe_run_oauth_flow_impl(PGconn *conn)
27552802

27562803
if (status==PGRES_POLLING_FAILED)
27572804
gotoerror_return;
2758-
elseif (status!=PGRES_POLLING_OK)
2759-
{
2760-
/* not done yet */
2761-
returnstatus;
2762-
}
2805+
elseif (status==PGRES_POLLING_OK)
2806+
break;/* done! */
27632807

2764-
break;
2808+
/*
2809+
* This request is still running.
2810+
*
2811+
* Make sure that stale events don't cause us to come back
2812+
* early. (Currently, this can occur only with kqueue.) If
2813+
* this is forgotten, the multiplexer can get stuck in a
2814+
* signaled state and we'll burn CPU cycles pointlessly.
2815+
*/
2816+
if (!comb_multiplexer(actx))
2817+
gotoerror_return;
2818+
2819+
returnstatus;
27652820
}
27662821

27672822
caseOAUTH_STEP_WAIT_INTERVAL:

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp