Albert Lee : server: Support event ports on Solaris.
Alexandre Julliard
julliard at winehq.org
Tue Nov 24 12:40:23 CST 2009
Module: wine
Branch: master
Commit: 01b972d63905a42688e8b8ce8f9ed5cf65e2d731
URL: http://source.winehq.org/git/wine.git/?a=commit;h=01b972d63905a42688e8b8ce8f9ed5cf65e2d731
Author: Albert Lee <trisk at forkgnu.org>
Date: Fri Nov 20 18:35:26 2009 -0500
server: Support event ports on Solaris.
---
configure | 2 +
configure.ac | 2 +
include/config.h.in | 6 +++
server/fd.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 115 insertions(+), 0 deletions(-)
diff --git a/configure b/configure
index 15652b4..5893216 100755
--- a/configure
+++ b/configure
@@ -5727,6 +5727,7 @@ for ac_header in \
openssl/ssl.h \
png.h \
poll.h \
+ port.h \
process.h \
pthread.h \
pwd.h \
@@ -12109,6 +12110,7 @@ for ac_func in \
pipe2 \
poll \
popen \
+ port_create \
prctl \
pread \
pwrite \
diff --git a/configure.ac b/configure.ac
index a5f1b8a..9a382f3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -364,6 +364,7 @@ AC_CHECK_HEADERS(\
openssl/ssl.h \
png.h \
poll.h \
+ port.h \
process.h \
pthread.h \
pwd.h \
@@ -1709,6 +1710,7 @@ AC_CHECK_FUNCS(\
pipe2 \
poll \
popen \
+ port_create \
prctl \
pread \
pwrite \
diff --git a/include/config.h.in b/include/config.h.in
index 16b2e90..7a77d1f 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -591,6 +591,12 @@
/* Define to 1 if you have the `popen' function. */
#undef HAVE_POPEN
+/* Define to 1 if you have the `port_create' function. */
+#undef HAVE_PORT_CREATE
+
+/* Define to 1 if you have the <port.h> header file. */
+#undef HAVE_PORT_H
+
/* Define if we can use ppdev.h for parallel port access */
#undef HAVE_PPDEV
diff --git a/server/fd.c b/server/fd.c
index 9d2ac9d..9d8a06f 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -162,6 +162,10 @@ static inline int epoll_wait( int epfd, struct epoll_event *events, int maxevent
#endif /* linux && __i386__ && HAVE_STDINT_H */
+#if defined(HAVE_PORT_H) && defined(HAVE_PORT_CREATE)
+# include <port.h>
+# define USE_EVENT_PORTS
+#endif /* HAVE_PORT_H && HAVE_PORT_CREATE */
/* Because of the stupid Posix locking semantics, we need to keep
* track of all file descriptors referencing a given file, and not
@@ -676,6 +680,107 @@ static inline void main_loop_epoll(void)
}
}
+#elif defined(USE_EVENT_PORTS)
+
+static int port_fd = -1;
+
+static inline void init_epoll(void)
+{
+ port_fd = port_create();
+}
+
+static inline void set_fd_epoll_events( struct fd *fd, int user, int events )
+{
+ int ret;
+
+ if (port_fd == -1) return;
+
+ if (events == -1) /* stop waiting on this fd completely */
+ {
+ if (pollfd[user].fd == -1) return; /* already removed */
+ port_dissociate( port_fd, PORT_SOURCE_FD, fd->unix_fd );
+ }
+ else if (pollfd[user].fd == -1)
+ {
+ if (pollfd[user].events) return; /* stopped waiting on it, don't restart */
+ ret = port_associate( port_fd, PORT_SOURCE_FD, fd->unix_fd, events, (void *)user );
+ }
+ else
+ {
+ if (pollfd[user].events == events) return; /* nothing to do */
+ ret = port_associate( port_fd, PORT_SOURCE_FD, fd->unix_fd, events, (void *)user );
+ }
+
+ if (ret == -1)
+ {
+ if (errno == ENOMEM) /* not enough memory, give up on port_associate */
+ {
+ close( port_fd );
+ port_fd = -1;
+ }
+ else perror( "port_associate" ); /* should not happen */
+ }
+}
+
+static inline void remove_epoll_user( struct fd *fd, int user )
+{
+ if (port_fd == -1) return;
+
+ if (pollfd[user].fd != -1)
+ {
+ port_dissociate( port_fd, PORT_SOURCE_FD, fd->unix_fd );
+ }
+}
+
+static inline void main_loop_epoll(void)
+{
+ int i, nget, ret, timeout;
+ port_event_t events[128];
+
+ if (port_fd == -1) return;
+
+ while (active_users)
+ {
+ timeout = get_next_timeout();
+ nget = 1;
+
+ if (!active_users) break; /* last user removed by a timeout */
+ if (port_fd == -1) break; /* an error occurred with event completion */
+
+ if (timeout != -1)
+ {
+ struct timespec ts;
+
+ ts.tv_sec = timeout / 1000;
+ ts.tv_nsec = (timeout % 1000) * 1000000;
+ ret = port_getn( port_fd, events, sizeof(events)/sizeof(events[0]), &nget, &ts );
+ }
+ else ret = port_getn( port_fd, events, sizeof(events)/sizeof(events[0]), &nget, NULL );
+
+ if (ret == -1) break; /* an error occurred with event completion */
+
+ set_current_time();
+
+ /* put the events into the pollfd array first, like poll does */
+ for (i = 0; i < nget; i++)
+ {
+ long user = (long)events[i].portev_user;
+ pollfd[user].revents = events[i].portev_events;
+ }
+
+ /* read events from the pollfd array, as set_fd_events may modify them */
+ for (i = 0; i < nget; i++)
+ {
+ long user = (long)events[i].portev_user;
+ if (pollfd[user].revents) fd_poll_event( poll_users[user], pollfd[user].revents );
+ /* if we are still interested, reassociate the fd */
+ if (pollfd[user].fd != -1) {
+ port_associate( port_fd, PORT_SOURCE_FD, pollfd[user].fd, pollfd[user].events, (void *)user );
+ }
+ }
+ }
+}
+
#else /* HAVE_KQUEUE */
static inline void init_epoll(void) { }
More information about the wine-cvs
mailing list