[Android] Implement missing cancellation points

Rafaël Carré git at videolan.org
Sat Mar 31 22:07:07 CEST 2012


android | branch: master | Rafaël Carré <funman at videolan.org> | Sat Mar 31 16:06:39 2012 -0400| [adf3019a54abc164d8a1d9099f958dd7a986b06f] | committer: Rafaël Carré

Implement missing cancellation points

> http://git.videolan.org/gitweb.cgi/android.git/?a=commit;h=adf3019a54abc164d8a1d9099f958dd7a986b06f
---

 compile.sh                                 |    2 +-
 patches/0001-android-threads-support.patch |   93 ++++++++++++++++++++++-----
 2 files changed, 76 insertions(+), 19 deletions(-)

diff --git a/compile.sh b/compile.sh
index d172500..4dbccd6 100755
--- a/compile.sh
+++ b/compile.sh
@@ -38,7 +38,7 @@ fi
 export PATH=${ANDROID_NDK}/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin:${PATH}
 
 # 1/ libvlc, libvlccore and its plugins
-TESTED_HASH=544af798
+TESTED_HASH=842d0af
 if [ ! -d "vlc" ]; then
     echo "VLC source not found, cloning"
     git clone git://git.videolan.org/vlc.git vlc
diff --git a/patches/0001-android-threads-support.patch b/patches/0001-android-threads-support.patch
index d71d21a..5586256 100644
--- a/patches/0001-android-threads-support.patch
+++ b/patches/0001-android-threads-support.patch
@@ -1,4 +1,4 @@
-From 1efcbc25a531c7166939fc7ddd6fc1e9575b1c2e Mon Sep 17 00:00:00 2001
+From 45f522e1bce9582ac69af72af91f7dcb2eafcade Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Rafa=C3=ABl=20Carr=C3=A9?= <funman at videolan.org>
 Date: Sat, 10 Mar 2012 04:54:23 -0500
 Subject: [PATCH] android: threads support
@@ -24,15 +24,17 @@ TODO:
      * vlc_testcancel()
      * vlc_restorecancel()
      * vlc_control_cancel()
+     * vlc_sem_wait()
+     * msleep()
 
-timer, semaphores, rwlocks, mutexes, clock, mwait/msleep/mdate, threadvar
+timer, rwlocks, mutexes, clock, threadvar
 are 100% shared with linux so it'd be useless to have 2 copies.
 ---
  include/vlc_threads.h |   13 +++
- lib/error.c           |   16 ++++-
+ lib/error.c           |   16 +++-
  src/Makefile.am       |   17 ++++
- src/posix/thread.c    |  205 +++++++++++++++++++++++++++++++++++++++++++------
- 4 files changed, 226 insertions(+), 25 deletions(-)
+ src/posix/thread.c    |  245 +++++++++++++++++++++++++++++++++++++++++++------
+ 4 files changed, 261 insertions(+), 30 deletions(-)
 
 diff --git a/include/vlc_threads.h b/include/vlc_threads.h
 index ebf94e2..dad50b1 100644
@@ -103,7 +105,7 @@ index ef2ecdc..42f6b4e 100644
      vlc_mutex_unlock (&lock);
  }
 diff --git a/src/Makefile.am b/src/Makefile.am
-index 81b01fb..122cdd5 100644
+index 24632ac..848ccea 100644
 --- a/src/Makefile.am
 +++ b/src/Makefile.am
 @@ -196,6 +196,7 @@ libvlc_win32_rc.$(OBJEXT): libvlc_win32_rc.rc
@@ -152,7 +154,7 @@ index 81b01fb..122cdd5 100644
  	posix/dirs.c \
  	misc/atomic.c \
 diff --git a/src/posix/thread.c b/src/posix/thread.c
-index a7a4873..9fbd0d4 100644
+index a7a4873..598c692 100644
 --- a/src/posix/thread.c
 +++ b/src/posix/thread.c
 @@ -1,5 +1,5 @@
@@ -212,7 +214,7 @@ index a7a4873..9fbd0d4 100644
               action, error, vlc_threadid ());
      vlc_trace (function, file, line);
  
-@@ -335,6 +349,53 @@ void vlc_mutex_unlock (vlc_mutex_t *p_mutex)
+@@ -335,6 +349,57 @@ void vlc_mutex_unlock (vlc_mutex_t *p_mutex)
      VLC_THREAD_ASSERT ("unlocking mutex");
  }
  
@@ -228,6 +230,7 @@ index a7a4873..9fbd0d4 100644
 +
 +    bool killable;
 +    bool killed;
++    bool finished;
 +};
 +
 +static pthread_key_t thread_key = 0;
@@ -241,6 +244,7 @@ index a7a4873..9fbd0d4 100644
 +        .cleaners = NULL,
 +        .killable = false,
 +        .killed   = false,
++        .finished = false,
 +        .entry    = NULL,
 +        .data     = NULL,
 +    };
@@ -260,13 +264,15 @@ index a7a4873..9fbd0d4 100644
 +    vlc_thread_t thread = data;
 +    if (pthread_setspecific(thread_key, thread))
 +        abort();
-+    return thread->entry(thread->data);
++    void *ret = thread->entry(thread->data);
++    thread->finished = true;
++    return ret;
 +}
 +
  /**
   * Initializes a condition variable.
   */
-@@ -428,7 +489,22 @@ void vlc_cond_broadcast (vlc_cond_t *p_condvar)
+@@ -428,7 +493,22 @@ void vlc_cond_broadcast (vlc_cond_t *p_condvar)
   */
  void vlc_cond_wait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex)
  {
@@ -289,7 +295,7 @@ index a7a4873..9fbd0d4 100644
      VLC_THREAD_ASSERT ("waiting on condition");
  }
  
-@@ -450,10 +526,25 @@ void vlc_cond_wait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex)
+@@ -450,10 +530,25 @@ void vlc_cond_wait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex)
  int vlc_cond_timedwait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex,
                          mtime_t deadline)
  {
@@ -315,7 +321,25 @@ index a7a4873..9fbd0d4 100644
      return val;
  }
  
-@@ -720,7 +811,21 @@ static int vlc_clone_attr (vlc_thread_t *th, pthread_attr_t *attr,
+@@ -532,10 +627,14 @@ void vlc_sem_wait (vlc_sem_t *sem)
+ 
+     val = EINVAL;
+ #else
+-    do
+-        if (likely(sem_wait (sem) == 0))
++    do {
++        vlc_testcancel();
++        struct timespec t = mtime_to_ts (mdate());
++        t.tv_nsec += 10 * 1000 * 1000;
++        if (likely(sem_timedwait (sem, &t) == 0))
+             return;
+-    while ((val = errno) == EINTR);
++        val = errno;
++    } while (val == EINTR || val == ETIMEDOUT);
+ #endif
+ 
+     VLC_THREAD_ASSERT ("locking semaphore");
+@@ -720,7 +819,22 @@ static int vlc_clone_attr (vlc_thread_t *th, pthread_attr_t *attr,
      assert (ret == 0); /* fails iif VLC_STACKSIZE is invalid */
  #endif
  
@@ -326,6 +350,7 @@ index a7a4873..9fbd0d4 100644
 +
 +    thread->killable = true;
 +    thread->killed = false;
++    thread->finished = false,
 +    thread->cond = NULL;
 +    thread->lock = NULL;
 +    thread->cleaners = NULL;
@@ -338,18 +363,23 @@ index a7a4873..9fbd0d4 100644
      pthread_sigmask (SIG_SETMASK, &oldset, NULL);
      pthread_attr_destroy (attr);
      return ret;
-@@ -761,8 +866,9 @@ int vlc_clone (vlc_thread_t *th, void *(*entry) (void *), void *data,
+@@ -761,8 +875,14 @@ int vlc_clone (vlc_thread_t *th, void *(*entry) (void *), void *data,
   */
  void vlc_join (vlc_thread_t handle, void **result)
  {
 -    int val = pthread_join (handle, result);
++    do {
++        vlc_testcancel();
++        msleep(CLOCK_FREQ / 100);
++    } while (!handle->finished);
++
 +    int val = pthread_join (handle->thread, result);
      VLC_THREAD_ASSERT ("joining thread");
 +    free(handle);
  }
  
  /**
-@@ -828,6 +934,7 @@ int vlc_set_priority (vlc_thread_t th, int priority)
+@@ -828,6 +948,7 @@ int vlc_set_priority (vlc_thread_t th, int priority)
              return VLC_EGENERIC;
      }
  #else
@@ -357,7 +387,7 @@ index a7a4873..9fbd0d4 100644
      (void) priority;
  #endif
      return VLC_SUCCESS;
-@@ -842,10 +949,25 @@ int vlc_set_priority (vlc_thread_t th, int priority)
+@@ -842,10 +963,25 @@ int vlc_set_priority (vlc_thread_t th, int priority)
   */
  void vlc_cancel (vlc_thread_t thread_id)
  {
@@ -387,7 +417,7 @@ index a7a4873..9fbd0d4 100644
  }
  
  /**
-@@ -858,11 +980,13 @@ void vlc_cancel (vlc_thread_t thread_id)
+@@ -858,11 +994,13 @@ void vlc_cancel (vlc_thread_t thread_id)
   */
  int vlc_savecancel (void)
  {
@@ -405,7 +435,7 @@ index a7a4873..9fbd0d4 100644
  }
  
  /**
-@@ -872,18 +996,19 @@ int vlc_savecancel (void)
+@@ -872,18 +1010,19 @@ int vlc_savecancel (void)
   */
  void vlc_restorecancel (int state)
  {
@@ -431,7 +461,7 @@ index a7a4873..9fbd0d4 100644
  #endif
  }
  
-@@ -896,13 +1021,47 @@ void vlc_restorecancel (int state)
+@@ -896,13 +1035,48 @@ void vlc_restorecancel (int state)
   */
  void vlc_testcancel (void)
  {
@@ -445,6 +475,7 @@ index a7a4873..9fbd0d4 100644
 +    for (vlc_cleanup_t *p = thread->cleaners; p != NULL; p = p->next)
 +        p->proc (p->data);
 +
++    thread->finished = true;
 +    pthread_exit(NULL);
  }
  
@@ -482,6 +513,32 @@ index a7a4873..9fbd0d4 100644
  }
  
  /**
+@@ -979,8 +1153,23 @@ void msleep (mtime_t delay)
+     while (clock_nanosleep (vlc_clock_id, 0, &ts, &ts) == EINTR);
+ 
+ #else
+-    while (nanosleep (&ts, &ts) == -1)
+-        assert (errno == EINTR);
++    vlc_testcancel();
++    for (;;) {
++        struct timespec t = { 0, 10 * 1000 * 1000 };
++        if (t.tv_nsec < ts.tv_nsec)
++            t.tv_nsec = ts.tv_nsec;
++        while (nanosleep (&t, &t) == -1) {
++            vlc_testcancel();
++            assert (errno == EINTR);
++        }
++
++        ts.tv_nsec -= 10 * 1000 * 1000;
++        if (ts.tv_nsec < 0) {
++            if (--ts.tv_sec < 0)
++                return;
++            ts.tv_nsec += 1000 * 1000 * 1000;
++        }
++    }
+ 
+ #endif
+ }
 -- 
 1.7.9.1
 



More information about the Android mailing list