Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
969f57c2
Commit
969f57c2
authored
Sep 23, 2004
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added support for epoll() as an alternative to poll() (based on the
work of Shachar Shemesh and Mike McCormack).
parent
24ab49e2
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
130 additions
and
0 deletions
+130
-0
configure
configure
+4
-0
configure.ac
configure.ac
+2
-0
config.h.in
include/config.h.in
+6
-0
fd.c
server/fd.c
+118
-0
No files found.
configure
View file @
969f57c2
...
...
@@ -16277,6 +16277,7 @@ fi
for
ac_func
in
\
_lwp_create
\
_lwp_self
\
...
...
@@ -16289,6 +16290,7 @@ for ac_func in \
_vsnprintf
\
chsize
\
clone
\
epoll_create
\
finite
\
fpclass
\
fstatfs
\
...
...
@@ -16525,6 +16527,7 @@ done
for
ac_header
in
\
arpa/inet.h
\
arpa/nameser.h
\
...
...
@@ -16575,6 +16578,7 @@ for ac_header in \
sys/cdio.h
\
sys/elf32.h
\
sys/errno.h
\
sys/epoll.h
\
sys/exec_elf.h
\
sys/file.h
\
sys/filio.h
\
...
...
configure.ac
View file @
969f57c2
...
...
@@ -1065,6 +1065,7 @@ AC_CHECK_FUNCS(\
_vsnprintf \
chsize \
clone \
epoll_create \
finite \
fpclass \
fstatfs \
...
...
@@ -1165,6 +1166,7 @@ AC_CHECK_HEADERS(\
sys/cdio.h \
sys/elf32.h \
sys/errno.h \
sys/epoll.h \
sys/exec_elf.h \
sys/file.h \
sys/filio.h \
...
...
include/config.h.in
View file @
969f57c2
...
...
@@ -80,6 +80,9 @@
/* Define to 1 if you have the <elf.h> header file. */
#undef HAVE_ELF_H
/* Define to 1 if you have the `epoll_create' function. */
#undef HAVE_EPOLL_CREATE
/* Define to 1 if you have the `finite' function. */
#undef HAVE_FINITE
...
...
@@ -617,6 +620,9 @@
/* Define to 1 if you have the <sys/elf32.h> header file. */
#undef HAVE_SYS_ELF32_H
/* Define to 1 if you have the <sys/epoll.h> header file. */
#undef HAVE_SYS_EPOLL_H
/* Define to 1 if you have the <sys/errno.h> header file. */
#undef HAVE_SYS_ERRNO_H
...
...
server/fd.c
View file @
969f57c2
...
...
@@ -33,6 +33,12 @@
#ifdef HAVE_SYS_POLL_H
#include <sys/poll.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_SYS_EPOLL_H
#include <sys/epoll.h>
#endif
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
...
...
@@ -48,6 +54,10 @@
#include "winreg.h"
#include "winternl.h"
#if defined(HAVE_SYS_EPOLL_H) && defined(HAVE_EPOLL_CREATE)
# define USE_EPOLL
#endif
/* Because of the stupid Posix locking semantics, we need to keep
* track of all file descriptors referencing a given file, and not
* close a single one until all the locks are gone (sigh).
...
...
@@ -236,6 +246,58 @@ static int active_users; /* current number of active users */
static
int
allocated_users
;
/* count of allocated entries in the array */
static
struct
fd
**
freelist
;
/* list of free entries in the array */
#ifdef USE_EPOLL
static
int
epoll_fd
;
static
struct
epoll_event
*
epoll_events
;
/* set the events that epoll waits for on this fd; helper for set_fd_events */
static
inline
void
set_fd_epoll_events
(
struct
fd
*
fd
,
int
user
,
int
events
)
{
struct
epoll_event
ev
;
int
ctl
;
if
(
epoll_fd
==
-
1
)
return
;
if
(
events
==
-
1
)
/* stop waiting on this fd completely */
{
if
(
pollfd
[
user
].
fd
==
-
1
)
return
;
/* already removed */
ctl
=
EPOLL_CTL_DEL
;
}
else
if
(
pollfd
[
user
].
fd
==
-
1
)
{
if
(
pollfd
[
user
].
events
)
return
;
/* stopped waiting on it, don't restart */
ctl
=
EPOLL_CTL_ADD
;
}
else
{
if
(
pollfd
[
user
].
events
==
events
)
return
;
/* nothing to do */
ctl
=
EPOLL_CTL_MOD
;
}
ev
.
events
=
events
;
ev
.
data
.
u32
=
user
;
if
(
epoll_ctl
(
epoll_fd
,
ctl
,
fd
->
unix_fd
,
&
ev
)
==
-
1
)
{
if
(
errno
==
ENOMEM
)
/* not enough memory, give up on epoll */
{
close
(
epoll_fd
);
epoll_fd
=
-
1
;
}
else
perror
(
"epoll_ctl"
);
/* should not happen */
}
}
#else
/* USE_EPOLL */
static
inline
void
set_fd_epoll_events
(
struct
fd
*
fd
,
int
user
,
int
events
)
{
}
#endif
/* USE_EPOLL */
/* add a user in the poll array and return its index, or -1 on failure */
static
int
add_poll_user
(
struct
fd
*
fd
)
{
...
...
@@ -263,6 +325,16 @@ static int add_poll_user( struct fd *fd )
}
poll_users
=
newusers
;
pollfd
=
newpoll
;
#ifdef USE_EPOLL
if
(
!
allocated_users
)
epoll_fd
=
epoll_create
(
new_count
);
if
(
epoll_fd
!=
-
1
)
{
struct
epoll_event
*
new_events
;
if
(
!
(
new_events
=
realloc
(
epoll_events
,
new_count
*
sizeof
(
*
epoll_events
)
)))
return
-
1
;
epoll_events
=
new_events
;
}
#endif
allocated_users
=
new_count
;
}
ret
=
nb_users
++
;
...
...
@@ -280,6 +352,14 @@ static void remove_poll_user( struct fd *fd, int user )
{
assert
(
user
>=
0
);
assert
(
poll_users
[
user
]
==
fd
);
#ifdef USE_EPOLL
if
(
epoll_fd
!=
-
1
&&
pollfd
[
user
].
fd
!=
-
1
)
{
struct
epoll_event
dummy
;
epoll_ctl
(
epoll_fd
,
EPOLL_CTL_DEL
,
fd
->
unix_fd
,
&
dummy
);
}
#endif
pollfd
[
user
].
fd
=
-
1
;
pollfd
[
user
].
events
=
0
;
pollfd
[
user
].
revents
=
0
;
...
...
@@ -340,6 +420,41 @@ void main_loop(void)
{
int
i
,
ret
,
timeout
;
#ifdef USE_EPOLL
assert
(
POLLIN
==
EPOLLIN
);
assert
(
POLLOUT
==
EPOLLOUT
);
assert
(
POLLERR
==
EPOLLERR
);
assert
(
POLLHUP
==
EPOLLHUP
);
if
(
epoll_fd
!=
-
1
)
{
while
(
active_users
)
{
timeout
=
get_next_timeout
();
if
(
!
active_users
)
break
;
/* last user removed by a timeout */
if
(
epoll_fd
==
-
1
)
break
;
/* an error occurred with epoll */
ret
=
epoll_wait
(
epoll_fd
,
epoll_events
,
allocated_users
,
timeout
);
/* put the events into the pollfd array first, like poll does */
for
(
i
=
0
;
i
<
ret
;
i
++
)
{
int
user
=
epoll_events
[
i
].
data
.
u32
;
pollfd
[
user
].
revents
=
epoll_events
[
i
].
events
;
}
/* read events from the pollfd array, as set_fd_events may modify them */
for
(
i
=
0
;
i
<
ret
;
i
++
)
{
int
user
=
epoll_events
[
i
].
data
.
u32
;
if
(
pollfd
[
user
].
revents
)
fd_poll_event
(
poll_users
[
user
],
pollfd
[
user
].
revents
);
}
}
}
/* fall through to normal poll loop */
#endif
/* USE_EPOLL */
while
(
active_users
)
{
timeout
=
get_next_timeout
();
...
...
@@ -841,6 +956,9 @@ void set_fd_events( struct fd *fd, int events )
{
int
user
=
fd
->
poll_index
;
assert
(
poll_users
[
user
]
==
fd
);
set_fd_epoll_events
(
fd
,
user
,
events
);
if
(
events
==
-
1
)
/* stop waiting on this fd completely */
{
pollfd
[
user
].
fd
=
-
1
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment