Module: wine Branch: master Commit: 01b972d63905a42688e8b8ce8f9ed5cf65e2d731 URL: http://source.winehq.org/git/wine.git/?a=commit;h=01b972d63905a42688e8b8ce8f...
Author: Albert Lee trisk@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) { }