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

Reply via email to