Add epoll_create/epoll_ctl/epoll_wait/epoll_pwait support to libsdp.
When creating epoll set, make it twice as large, for shadow fd data.
When doing epoll_ctl, perform the same operation on shadow fd as well.
(If the shadow fd is closed, it will be automatically removed from epoll
set).
When waiting (epoll_wait or epoll_pwait), no need to perform special
work, since it returns user data and not file descriptors.
Signed-off-by: Yossi Etigin <[EMAIL PROTECTED]>
--
diff --git a/src/port.c b/src/port.c
index 340c2a5..9cf73a5 100644
--- a/src/port.c
+++ b/src/port.c
@@ -49,6 +49,7 @@
#include <fcntl.h>
#include <signal.h>
#include <sys/poll.h>
+#include <sys/epoll.h>
/*
* SDP specific includes
*/
@@ -175,6 +176,33 @@ typedef int (
unsigned long int nfds,
int timeout);
+typedef int (
+ *epoll_create_func_t ) (
+ int size);
+
+typedef int (
+ *epoll_ctl_func_t ) (
+ int epfd,
+ int op,
+ int fd,
+ struct epoll_event *event);
+
+typedef int (
+ *epoll_wait_func_t ) (
+ int epfd,
+ struct epoll_event *events,
+ int maxevents,
+ int timeout);
+
+typedef int (
+ *epoll_pwait_func_t ) (
+ int epfd,
+ struct epoll_event *events,
+ int maxevents,
+ int timeout,
+ const sigset_t *sigmask);
+
+
struct socket_lib_funcs
{
ioctl_func_t ioctl;
@@ -193,6 +221,10 @@ struct socket_lib_funcs
select_func_t select;
pselect_func_t pselect;
poll_func_t poll;
+ epoll_create_func_t epoll_create;
+ epoll_ctl_func_t epoll_ctl;
+ epoll_wait_func_t epoll_wait;
+ epoll_pwait_func_t epoll_pwait;
};
/* socket_lib_funcs */
static int simple_sdp_library;
@@ -2506,6 +2538,137 @@ poll(
}
/* poll */
/* ========================================================================= */
+/*..epoll_create -- replacement socket call. */
+/*
+ Need to make the size twice as large for shadow fds
+*/
+int
+epoll_create(
+ int size )
+{
+ int epfd;
+
+ if (init_status == 0) __sdp_init();
+
+ if ( NULL == _socket_funcs.epoll_create ) {
+ __sdp_log( 9, "Error epoll_create: no implementation for
epoll_create found\n" );
+ return -1;
+ }
+
+ __sdp_log( 2, "EPOLL_CREATE: <%s:%d>\n", program_invocation_short_name,
size );
+
+ epfd = _socket_funcs.epoll_create( size * 2 );
+
+ __sdp_log( 2, "EPOLL_CREATE: <%s:%d> return %d\n",
+ program_invocation_short_name, size, epfd );
+ return epfd;
+}
/* epoll_create */
+
+/* ========================================================================= */
+/*..epoll_ctl -- replacement socket call. */
+/*
+ Need to add/delete/modify shadow fds as well
+*/
+int
+epoll_ctl(
+ int epfd,
+ int op,
+ int fd,
+ struct epoll_event *event )
+{
+ int ret, shadow_fd, ret2;
+
+ if (init_status == 0) __sdp_init();
+
+ if ( NULL == _socket_funcs.epoll_ctl ) {
+ __sdp_log( 9, "Error epoll_ctl: no implementation for epoll_ctl
found\n" );
+ return -1;
+ }
+
+ __sdp_log( 2, "EPOLL_CTL: <%s:%d> op <%d:%d>\n",
+ program_invocation_short_name, epfd, op, fd );
+
+ ret = _socket_funcs.epoll_ctl( epfd, op, fd, event );
+
+ shadow_fd = get_shadow_fd_by_fd(fd);
+ if ( shadow_fd != -1 ) {
+ ret2 = _socket_funcs.epoll_ctl( epfd, op, shadow_fd, event );
+ if ( ret2 < 0 ) {
+ __sdp_log( 9, "Error epoll_ctl <%s:%d:%d>",
+ program_invocation_short_name, fd, shadow_fd
);
+ return ret2;
+ }
+ }
+
+ __sdp_log( 2, "EPOLL_CTL: <%s:%d> return <%d>\n",
+ program_invocation_short_name, epfd, ret );
+ return ret;
+}
/* epoll_ctl */
+
+/* ========================================================================= */
+/*..epoll_wait -- replacement socket call. */
+/*
+ We don't care who generated the event because all we get is user-context
+ values.
+*/
+int
+epoll_wait(
+ int epfd,
+ struct epoll_event *events,
+ int maxevents,
+ int timeout )
+{
+ int ret;
+
+ if (init_status == 0) __sdp_init();
+
+ if ( NULL == _socket_funcs.epoll_wait ) {
+ __sdp_log( 9, "Error epoll_wait: no implementation for epoll_wait
found\n" );
+ return -1;
+ }
+
+ __sdp_log( 2, "EPOLL_WAIT: <%s:%d>\n", program_invocation_short_name,
epfd );
+
+ ret = _socket_funcs.epoll_wait( epfd, events, maxevents, timeout );
+
+ __sdp_log( 2, "EPOLL_WAIT: <%s:%d> return <%d>\n",
program_invocation_short_name,
+ epfd, ret );
+ return ret;
+}
/* epoll_wait */
+
+/* ========================================================================= */
+/*..epoll_pwait -- replacement socket call. */
+/*
+ We don't care who generated the event because all we get is user-context
+ values.
+*/
+int
+epoll_pwait(
+ int epfd,
+ struct epoll_event *events,
+ int maxevents,
+ int timeout,
+ const sigset_t *sigmask )
+{
+ int ret;
+
+ if (init_status == 0) __sdp_init();
+
+ if ( NULL == _socket_funcs.epoll_pwait ) {
+ __sdp_log( 9, "Error epoll_pwait: no implementation for epoll_pwait
found\n" );
+ return -1;
+ }
+
+ __sdp_log( 2, "EPOLL_PWAIT: <%s:%d>\n", program_invocation_short_name,
epfd );
+
+ ret = _socket_funcs.epoll_pwait( epfd, events, maxevents, timeout,
sigmask );
+
+ __sdp_log( 2, "EPOLL_PWAIT: <%s:%d> return <%d>\n",
program_invocation_short_name,
+ epfd, ret );
+ return ret;
+}
/* epoll_pwait */
+
+/* ========================================================================= */
/* --------------------------------------------------------------------- */
/* */
@@ -2640,6 +2803,26 @@ __sdp_init(
fprintf( stderr, "%s\n", error_str );
}
+ _socket_funcs.epoll_create = dlsym( __libc_dl_handle, "epoll_create" );
+ if ( NULL != ( error_str = dlerror( ) ) ) {
+ fprintf( stderr, "%s\n", error_str );
+ }
+
+ _socket_funcs.epoll_ctl = dlsym( __libc_dl_handle, "epoll_ctl" );
+ if ( NULL != ( error_str = dlerror( ) ) ) {
+ fprintf( stderr, "%s\n", error_str );
+ }
+
+ _socket_funcs.epoll_wait = dlsym( __libc_dl_handle, "epoll_wait" );
+ if ( NULL != ( error_str = dlerror( ) ) ) {
+ fprintf( stderr, "%s\n", error_str );
+ }
+
+ _socket_funcs.epoll_pwait = dlsym( __libc_dl_handle, "epoll_pwait" );
+ if ( NULL != ( error_str = dlerror( ) ) ) {
+ fprintf( stderr, "%s\n", error_str );
+ }
+
if ( getenv( "SIMPLE_LIBSDP" ) != NULL ) {
simple_sdp_library = 1;
}
_______________________________________________
ewg mailing list
ewg@lists.openfabrics.org
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ewg