[ewg] ***SPAM*** [PATCH] libsdp: Add epoll support

Yossi Etigin yossi.openib at gmail.com
Mon Dec 8 08:29:09 PST 2008


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 <yosefe at voltaire.com>

--

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;
 	}



More information about the ewg mailing list