[vlc-devel] [PATCH 4/5] vlccore: implement timeout-free poll()

KO Myung-Hun komh78 at gmail.com
Sat Mar 2 18:33:27 CET 2013



Rémi Denis-Courmont wrote:
> Le samedi 2 mars 2013 17:11:09, KO Myung-Hun a écrit :
>> ---
>>  include/vlc_threads.h |  112
>> +++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 103
>> insertions(+), 9 deletions(-)
>>
>> diff --git a/include/vlc_threads.h b/include/vlc_threads.h
>> index 12b56fd..475eaec 100644
>> --- a/include/vlc_threads.h
>> +++ b/include/vlc_threads.h
>> @@ -385,23 +385,117 @@ struct vlc_cleanup_t
>>  #endif /* !LIBVLC_USE_PTHREAD_CLEANUO */
>>
>>  #ifndef LIBVLC_USE_PTHREAD_CANCEL
>> +# include <unistd.h>
>> +# include <sys/socket.h>
> 
> Not that I care personally, but does this not break Windows?
> 

I'm not sure.

>> +
>> +# ifndef INT64_C
>> +#  define INT64_C(c) (c ## LL)
>> +# endif
> 
> int64_t is not necessarily long long.
> 

Otherwise, what it can be ?

>> +
>> +typedef struct
>> +{
>> +    int            cancel[2];
>> +    vlc_mutex_t    mutex;
>> +    vlc_cond_t     cond;
>> +    struct pollfd* fds;
>> +    unsigned       nfds;
>> +} vlc_poll_thread_data_t;
>> +
>> +static inline void *vlc_poll_thread (void* arg)
>> +{
>> +    vlc_poll_thread_data_t *data = (vlc_poll_thread_data_t *)arg;
>> +
>> +    int val = poll (data->fds, data->nfds, -1);
>> +
>> +    if (data->fds[data->nfds - 1].revents & POLLIN ) /* Canceled ? */
>> +        val = 0;
>> +    else
>> +        vlc_cond_signal (&data->cond);
>> +
>> +    return (void *)val;
>> +}
>> +
>> +static inline void vlc_poll_thread_cleanup (void *arg)
>> +{
>> +    vlc_poll_thread_data_t *data = (vlc_poll_thread_data_t *)arg;
>> +
>> +    /* Wake up if vlc_poll_thread() is sleeping */
>> +    write (data->cancel[1], &data->cancel[1], sizeof (data->cancel[1]));
>> +
>> +    vlc_mutex_unlock (&data->mutex );
>> +
>> +    vlc_cond_destroy (&data->cond);
>> +    vlc_mutex_destroy (&data->mutex);
>> +
>> +    close (data->cancel[0]);
>> +    close (data->cancel[1]);
>> +}
>> +
>>  /* poll() with cancellation */
>>  static inline int vlc_poll (struct pollfd *fds, unsigned nfds, int
>> timeout) {
>> -    int val;
>> +    if (!timeout)
>> +        return poll (fds, nfds, timeout);
> 
> That's wrong. poll() is always a cancellation point even if the timeout is 
> zeor.
> 

Ok.

>> +
>> +    vlc_poll_thread_data_t data;
>> +    struct pollfd          newfds[nfds + 1];
>> +
>> +    vlc_thread_t  th;
>> +    void         *val;
>> +
>> +    socketpair (AF_LOCAL, SOCK_STREAM, 0, data.cancel);
>> +
>> +    vlc_mutex_init (&data.mutex);
>> +    vlc_cond_init (&data.cond);
>>
>> -    do
>> +    memcpy (newfds, fds, sizeof (*fds) * nfds);
>> +    newfds[nfds].fd      = data.cancel[0];
>> +    newfds[nfds].events  = POLLIN;
>> +    newfds[nfds].revents = 0;
>> +
>> +    data.fds  = newfds;
>> +    data.nfds = nfds + 1;
>> +
>> +    if (vlc_clone (&th, vlc_poll_thread, &data,
>> VLC_THREAD_PRIORITY_INPUT)) {
>> -        int ugly_timeout = ((unsigned)timeout >= 50) ? 50 : timeout;
>> -        if (timeout >= 0)
>> -            timeout -= ugly_timeout;
>> +        vlc_cond_destroy (&data.cond);
>> +        vlc_mutex_destroy (&data.mutex);
>>
>> -        vlc_testcancel ();
>> -        val = poll (fds, nfds, ugly_timeout);
>> +        close (data.cancel[0]);
>> +        close (data.cancel[1]);
>> +
>> +        return -1;
>>      }
>> -    while (val == 0 && timeout != 0);
>>
>> -    return val;
>> +    vlc_mutex_lock (&data.mutex);
>> +
>> +    vlc_cleanup_push (vlc_poll_thread_cleanup, &data);
>> +
>> +    if (timeout < 0)
>> +        vlc_cond_wait (&data.cond, &data.mutex);
>> +    else
>> +        vlc_cond_timedwait (&data.cond, &data.mutex,
>> +                            mdate () + timeout * CLOCK_FREQ / 1000);
>> +
>> +    vlc_cleanup_pop();
>> +
>> +    /* Wake up if vlcl_poll_thread() is sleeping */
>> +    write (data.cancel[1], &data.cancel[1], sizeof (data.cancel[1]));
>> +
>> +    vlc_mutex_unlock (&data.mutex);
>> +
>> +    /* Get a return value */
>> +    vlc_join (th, &val);
>> +
>> +    memcpy (fds, newfds, sizeof(*fds) * nfds);
>> +
>> +    vlc_cond_destroy (&data.cond);
>> +    vlc_mutex_destroy (&data.mutex);
>> +
>> +    close (data.cancel[0]);
>> +    close (data.cancel[1]);
>> +
>> +    return (int)val;
>>  }
>>  # define poll(u,n,t) vlc_poll(u, n, t)
> 
> And that's quite much code for an inline function.
> 

Right, too long. ^^

-- 
KO Myung-Hun

Using Mozilla SeaMonkey 2.7.2
Under OS/2 Warp 4 for Korean with FixPak #15
In VirtualBox v4.1.22 on Intel Core i7-3615QM 2.30GHz with 8GB RAM

Korean OS/2 User Community : http://www.ecomstation.co.kr




More information about the vlc-devel mailing list