[vlc-commits] os2: implement poll() with timeout free cancellation
KO Myung-Hun
git at videolan.org
Tue Mar 5 17:44:44 CET 2013
vlc | branch: master | KO Myung-Hun <komh at chollian.net> | Sun Mar 3 00:02:37 2013 +0900| [73f271093e112dceeefa73fac75402a3a9c102c4] | committer: Rémi Denis-Courmont
os2: implement poll() with timeout free cancellation
Signed-off-by: Rémi Denis-Courmont <remi at remlab.net>
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=73f271093e112dceeefa73fac75402a3a9c102c4
---
include/vlc_threads.h | 5 +++
src/os2/thread.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 101 insertions(+)
diff --git a/include/vlc_threads.h b/include/vlc_threads.h
index 12b56fd..ae83588 100644
--- a/include/vlc_threads.h
+++ b/include/vlc_threads.h
@@ -386,6 +386,9 @@ struct vlc_cleanup_t
#ifndef LIBVLC_USE_PTHREAD_CANCEL
/* poll() with cancellation */
+# ifdef __OS2__
+int vlc_poll (struct pollfd *fds, unsigned nfds, int timeout);
+# else
static inline int vlc_poll (struct pollfd *fds, unsigned nfds, int timeout)
{
int val;
@@ -403,6 +406,8 @@ static inline int vlc_poll (struct pollfd *fds, unsigned nfds, int timeout)
return val;
}
+# endif
+
# define poll(u,n,t) vlc_poll(u, n, t)
#endif /* LIBVLC_USE_PTHREAD_CANCEL */
diff --git a/src/os2/thread.c b/src/os2/thread.c
index ef439b9..1a40281 100644
--- a/src/os2/thread.c
+++ b/src/os2/thread.c
@@ -39,6 +39,12 @@
#include <errno.h>
#include <time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <sys/time.h>
+#include <sys/select.h>
+
static vlc_threadvar_t thread_key;
/**
@@ -49,6 +55,7 @@ struct vlc_thread
TID tid;
HEV cancel_event;
HEV done_event;
+ int cancel_sock;
bool detached;
bool killable;
@@ -246,6 +253,8 @@ void vlc_mutex_unlock (vlc_mutex_t *p_mutex)
}
/*** Condition variables ***/
+#undef CLOCK_REALTIME
+#undef CLOCK_MONOTONIC
enum
{
CLOCK_REALTIME=0, /* must be zero for VLC_STATIC_COND */
@@ -459,6 +468,9 @@ retry:
{
DosCloseEventSem (th->cancel_event);
DosCloseEventSem (th->done_event );
+
+ soclose (th->cancel_sock);
+
free (th);
}
}
@@ -492,6 +504,10 @@ static int vlc_clone_attr (vlc_thread_t *p_handle, bool detached,
if( DosCreateEventSem (NULL, &th->done_event, 0, FALSE))
goto error;
+ th->cancel_sock = socket (AF_LOCAL, SOCK_STREAM, 0);
+ if( th->cancel_sock < 0 )
+ goto error;
+
th->tid = _beginthread (vlc_entry, NULL, 1024 * 1024, th);
if((int)th->tid == -1)
goto error;
@@ -508,6 +524,7 @@ static int vlc_clone_attr (vlc_thread_t *p_handle, bool detached,
return 0;
error:
+ soclose (th->cancel_sock);
DosCloseEventSem (th->cancel_event);
DosCloseEventSem (th->done_event);
free (th);
@@ -537,6 +554,8 @@ void vlc_join (vlc_thread_t th, void **result)
DosCloseEventSem( th->cancel_event );
DosCloseEventSem( th->done_event );
+ soclose( th->cancel_sock );
+
free( th );
}
@@ -574,6 +593,7 @@ static void vlc_cancel_self (PVOID self)
void vlc_cancel (vlc_thread_t thread_id)
{
DosPostEventSem( thread_id->cancel_event );
+ so_cancel( thread_id->cancel_sock );
}
int vlc_savecancel (void)
@@ -656,6 +676,82 @@ void vlc_control_cancel (int cmd, ...)
va_end (ap);
}
+static int vlc_select( int nfds, fd_set *rdset, fd_set *wrset, fd_set *exset,
+ struct timeval *timeout )
+{
+ struct vlc_thread *th = vlc_threadvar_get( thread_key );
+
+ int rc;
+
+ if( th )
+ {
+ FD_SET( th->cancel_sock, rdset );
+
+ nfds = MAX( nfds, th->cancel_sock + 1 );
+ }
+
+ rc = select( nfds, rdset, wrset, exset, timeout );
+
+ vlc_testcancel();
+
+ return rc;
+
+}
+
+int vlc_poll( struct pollfd *fds, unsigned nfds, int timeout )
+{
+ fd_set rdset, wrset, exset;
+
+ struct timeval tv = { 0, 0 };
+
+ int val = -1;
+
+ FD_ZERO( &rdset );
+ FD_ZERO( &wrset );
+ FD_ZERO( &exset );
+ for( unsigned i = 0; i < nfds; i++ )
+ {
+ int fd = fds[ i ].fd;
+ if( val < fd )
+ val = fd;
+
+ if(( unsigned )fd >= FD_SETSIZE )
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if( fds[ i ].events & POLLIN )
+ FD_SET( fd, &rdset );
+ if( fds[ i ].events & POLLOUT )
+ FD_SET( fd, &wrset );
+ if( fds[ i ].events & POLLPRI )
+ FD_SET( fd, &exset );
+ }
+
+ if( timeout >= 0 )
+ {
+ div_t d = div( timeout, 1000 );
+ tv.tv_sec = d.quot;
+ tv.tv_usec = d.rem * 1000;
+ }
+
+ val = vlc_select( val + 1, &rdset, &wrset, &exset,
+ ( timeout >= 0 ) ? &tv : NULL );
+ if( val == -1 )
+ return -1;
+
+ for( unsigned i = 0; i < nfds; i++ )
+ {
+ int fd = fds[ i ].fd;
+ fds[ i ].revents = ( FD_ISSET( fd, &rdset ) ? POLLIN : 0 )
+ | ( FD_ISSET( fd, &wrset ) ? POLLOUT : 0 )
+ | ( FD_ISSET( fd, &exset ) ? POLLPRI : 0 );
+ }
+
+ return val;
+}
+
#define Q2LL( q ) ( *( long long * )&( q ))
/*** Clock ***/
More information about the vlc-commits
mailing list