1
0
mirror of https://gitlab.gnome.org/GNOME/glib.git synced 2025-03-31 04:43:06 +02:00

glib/gpoll W32: faster GPollFD lookup

Put all ptrs for GPollFDs that contribute handles into an array, the layout of which mirrors the handles array. This way finding GPollFD for a handle is a simple matter of knowing this handle's index in the handles array (which is something we always know). Removes the need to loop through all fds looking for the right one. And, with the message FD also passed along, it's now completely unnecessary to even pass fds to poll_rest() at all.

https://bugzilla.gnome.org/show_bug.cgi?id=785468
This commit is contained in:
Руслан Ижбулатов 2017-07-29 08:09:05 +00:00
parent 201977983e
commit 226ea94685

@ -129,12 +129,11 @@ g_poll (GPollFD *fds,
#ifdef G_OS_WIN32 #ifdef G_OS_WIN32
static int static int
poll_rest (GPollFD *msg_fd, poll_rest (GPollFD *msg_fd,
HANDLE *handles, HANDLE *handles,
gint nhandles, GPollFD *handle_to_fd[],
GPollFD *fds, gint nhandles,
guint nfds, gint timeout)
gint timeout)
{ {
DWORD ready; DWORD ready;
GPollFD *f; GPollFD *f;
@ -212,20 +211,15 @@ poll_rest (GPollFD *msg_fd,
/* If no timeout and handles to poll, recurse to poll them, /* If no timeout and handles to poll, recurse to poll them,
* too. * too.
*/ */
recursed_result = poll_rest (NULL, handles, nhandles, fds, nfds, 0); recursed_result = poll_rest (NULL, handles, handle_to_fd, nhandles, 0);
return (recursed_result == -1) ? -1 : 1 + recursed_result; return (recursed_result == -1) ? -1 : 1 + recursed_result;
} }
else if (ready >= WAIT_OBJECT_0 && ready < WAIT_OBJECT_0 + nhandles) else if (ready >= WAIT_OBJECT_0 && ready < WAIT_OBJECT_0 + nhandles)
{ {
for (f = fds; f < &fds[nfds]; ++f) f = handle_to_fd[ready - WAIT_OBJECT_0];
{ f->revents = f->events;
if ((HANDLE) f->fd == handles[ready - WAIT_OBJECT_0]) if (_g_main_poll_debug)
{ g_print (" got event %p\n", (HANDLE) f->fd);
f->revents = f->events;
if (_g_main_poll_debug)
g_print (" got event %p\n", (HANDLE) f->fd);
}
}
/* If no timeout and polling several handles, recurse to poll /* If no timeout and polling several handles, recurse to poll
* the rest of them. * the rest of them.
@ -234,10 +228,13 @@ poll_rest (GPollFD *msg_fd,
{ {
/* Remove the handle that fired */ /* Remove the handle that fired */
int i; int i;
for (i = ready - WAIT_OBJECT_0 + 1; i < nhandles; i++) for (i = ready - WAIT_OBJECT_0 + 1; i < nhandles; i++)
handles[i-1] = handles[i]; {
handles[i-1] = handles[i];
handle_to_fd[i-1] = handle_to_fd[i];
}
nhandles--; nhandles--;
recursed_result = poll_rest (NULL, handles, nhandles, fds, nfds, 0); recursed_result = poll_rest (NULL, handles, handle_to_fd, nhandles, 0);
return (recursed_result == -1) ? -1 : 1 + recursed_result; return (recursed_result == -1) ? -1 : 1 + recursed_result;
} }
return 1; return 1;
@ -252,6 +249,7 @@ g_poll (GPollFD *fds,
gint timeout) gint timeout)
{ {
HANDLE handles[MAXIMUM_WAIT_OBJECTS]; HANDLE handles[MAXIMUM_WAIT_OBJECTS];
GPollFD *handle_to_fd[MAXIMUM_WAIT_OBJECTS];
GPollFD *msg_fd = NULL; GPollFD *msg_fd = NULL;
GPollFD *f; GPollFD *f;
gint nhandles = 0; gint nhandles = 0;
@ -279,6 +277,7 @@ g_poll (GPollFD *fds,
{ {
if (_g_main_poll_debug) if (_g_main_poll_debug)
g_print (" %p", (HANDLE) f->fd); g_print (" %p", (HANDLE) f->fd);
handle_to_fd[nhandles] = f;
handles[nhandles++] = (HANDLE) f->fd; handles[nhandles++] = (HANDLE) f->fd;
} }
} }
@ -297,21 +296,21 @@ g_poll (GPollFD *fds,
/* First check if one or several of them are immediately /* First check if one or several of them are immediately
* available * available
*/ */
retval = poll_rest (msg_fd, handles, nhandles, fds, nfds, 0); retval = poll_rest (msg_fd, handles, handle_to_fd, nhandles, 0);
/* If not, and we have a significant timeout, poll again with /* If not, and we have a significant timeout, poll again with
* timeout then. Note that this will return indication for only * timeout then. Note that this will return indication for only
* one event, or only for messages. * one event, or only for messages.
*/ */
if (retval == 0 && (timeout == INFINITE || timeout > 0)) if (retval == 0 && (timeout == INFINITE || timeout > 0))
retval = poll_rest (msg_fd, handles, nhandles, fds, nfds, timeout); retval = poll_rest (msg_fd, handles, handle_to_fd, nhandles, timeout);
} }
else else
{ {
/* Just polling for one thing, so no need to check first if /* Just polling for one thing, so no need to check first if
* available immediately * available immediately
*/ */
retval = poll_rest (msg_fd, handles, nhandles, fds, nfds, timeout); retval = poll_rest (msg_fd, handles, handle_to_fd, nhandles, timeout);
} }
if (retval == -1) if (retval == -1)