Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Open sidebar
Steve Lhomme
VLC
Commits
6f3e18d5
Commit
6f3e18d5
authored
May 27, 2016
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
android: use generic condition variable and wait (fix #14586)
parent
54216384
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
60 additions
and
189 deletions
+60
-189
include/vlc_threads.h
include/vlc_threads.h
+2
-2
src/android/thread.c
src/android/thread.c
+58
-187
No files found.
include/vlc_threads.h
View file @
6f3e18d5
...
...
@@ -161,6 +161,8 @@ static inline int vlc_poll (struct pollfd *fds, unsigned nfds, int timeout)
# include <pthread.h>
# include <poll.h>
# define LIBVLC_USE_PTHREAD_CLEANUP 1
# define LIBVLC_NEED_SLEEP
# define LIBVLC_NEED_CONDVAR
# define LIBVLC_NEED_SEMAPHORE
# define LIBVLC_NEED_RWLOCK
...
...
@@ -168,8 +170,6 @@ typedef struct vlc_thread *vlc_thread_t;
#define VLC_THREAD_CANCELED NULL
typedef
pthread_mutex_t
vlc_mutex_t
;
#define VLC_STATIC_MUTEX PTHREAD_MUTEX_INITIALIZER
typedef
pthread_cond_t
vlc_cond_t
;
#define VLC_STATIC_COND PTHREAD_COND_INITIALIZER
typedef
pthread_key_t
vlc_threadvar_t
;
typedef
struct
vlc_timer
*
vlc_timer_t
;
...
...
src/android/thread.c
View file @
6f3e18d5
/*****************************************************************************
* thread.c : android pthread back-end for LibVLC
*****************************************************************************
* Copyright (C) 1999-201
2
VLC authors and VideoLAN
* Copyright (C) 1999-201
6
VLC authors and VideoLAN
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
...
...
@@ -48,15 +48,6 @@
#error no pthread monotonic clock support
#endif
/* helper */
static
struct
timespec
mtime_to_ts
(
mtime_t
date
)
{
lldiv_t
d
=
lldiv
(
date
,
CLOCK_FREQ
);
struct
timespec
ts
=
{
d
.
quot
,
d
.
rem
*
(
1000000000
/
CLOCK_FREQ
)
};
return
ts
;
}
/* debug */
#define vlc_assert(x) do { \
if (unlikely(!(x))) { \
...
...
@@ -166,13 +157,17 @@ void vlc_mutex_unlock (vlc_mutex_t *p_mutex)
struct
vlc_thread
{
pthread_t
thread
;
pthread_cond_t
*
cond
;
/// Non-null if thread waiting on cond
vlc_mutex_t
lock
;
/// Protects cond
vlc_sem_t
finished
;
void
*
(
*
entry
)(
void
*
);
void
*
data
;
struct
{
void
*
addr
;
/// Non-null if waiting on futex
vlc_mutex_t
lock
;
/// Protects futex address
}
wait
;
atomic_bool
killed
;
bool
killable
;
};
...
...
@@ -189,149 +184,13 @@ void vlc_threads_setup (libvlc_int_t *p_libvlc)
(
void
)
p_libvlc
;
}
/* cond */
void
vlc_cond_init
(
vlc_cond_t
*
condvar
)
{
#ifdef HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC_NP
if
(
unlikely
(
pthread_cond_init
(
condvar
,
NULL
)))
abort
();
#else
pthread_condattr_t
attr
;
pthread_condattr_init
(
&
attr
);
pthread_condattr_setclock
(
&
attr
,
CLOCK_MONOTONIC
);
if
(
unlikely
(
pthread_cond_init
(
condvar
,
&
attr
)))
abort
();
#endif
}
void
vlc_cond_init_daytime
(
vlc_cond_t
*
condvar
)
{
if
(
unlikely
(
pthread_cond_init
(
condvar
,
NULL
)))
abort
();
}
void
vlc_cond_destroy
(
vlc_cond_t
*
condvar
)
{
int
val
=
pthread_cond_destroy
(
condvar
);
VLC_THREAD_ASSERT
(
"destroying condition"
);
}
void
vlc_cond_signal
(
vlc_cond_t
*
condvar
)
{
int
val
=
pthread_cond_signal
(
condvar
);
VLC_THREAD_ASSERT
(
"signaling condition variable"
);
}
void
vlc_cond_broadcast
(
vlc_cond_t
*
condvar
)
{
pthread_cond_broadcast
(
condvar
);
}
void
vlc_cond_wait
(
vlc_cond_t
*
condvar
,
vlc_mutex_t
*
p_mutex
)
{
vlc_thread_t
th
=
thread
;
if
(
th
!=
NULL
)
{
vlc_testcancel
();
if
(
vlc_mutex_trylock
(
&
th
->
lock
)
==
0
)
{
th
->
cond
=
condvar
;
vlc_mutex_unlock
(
&
th
->
lock
);
}
else
{
/* The lock is already held by another thread.
* => That other thread has just cancelled this one. */
vlc_testcancel
();
/* Cancellation did not occur even though this thread is cancelled.
* => Cancellation is disabled. */
th
=
NULL
;
}
}
int
val
=
pthread_cond_wait
(
condvar
,
p_mutex
);
VLC_THREAD_ASSERT
(
"waiting on condition"
);
if
(
th
!=
NULL
)
{
vlc_mutex_lock
(
&
th
->
lock
);
th
->
cond
=
NULL
;
vlc_mutex_unlock
(
&
th
->
lock
);
vlc_testcancel
();
}
}
typedef
int
(
*
vlc_cond_wait_cb
)(
pthread_cond_t
*
,
pthread_mutex_t
*
,
const
struct
timespec
*
);
static
int
vlc_cond_timedwait_common
(
vlc_cond_t
*
condvar
,
vlc_mutex_t
*
mutex
,
const
struct
timespec
*
ts
,
vlc_cond_wait_cb
cb
)
{
vlc_thread_t
th
=
thread
;
if
(
th
!=
NULL
)
{
vlc_testcancel
();
if
(
vlc_mutex_trylock
(
&
th
->
lock
)
==
0
)
{
th
->
cond
=
condvar
;
vlc_mutex_unlock
(
&
th
->
lock
);
}
else
{
/* The lock is already held by another thread.
* => That other thread has just cancelled this one. */
vlc_testcancel
();
/* Cancellation did not occur even though this thread is cancelled.
* => Cancellation is disabled. */
th
=
NULL
;
}
}
int
val
=
cb
(
condvar
,
mutex
,
ts
);
if
(
val
!=
ETIMEDOUT
)
VLC_THREAD_ASSERT
(
"timed-waiting on condition"
);
if
(
th
!=
NULL
)
{
vlc_mutex_lock
(
&
th
->
lock
);
th
->
cond
=
NULL
;
vlc_mutex_unlock
(
&
th
->
lock
);
vlc_testcancel
();
}
return
val
;
}
int
vlc_cond_timedwait
(
vlc_cond_t
*
cond
,
vlc_mutex_t
*
mutex
,
mtime_t
deadline
)
{
struct
timespec
ts
=
mtime_to_ts
(
deadline
);
#ifdef HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC_NP
return
vlc_cond_timedwait_common
(
cond
,
mutex
,
&
ts
,
pthread_cond_timedwait_monotonic_np
);
#else
return
vlc_cond_timedwait_common
(
cond
,
mutex
,
&
ts
,
pthread_cond_timedwait
);
#endif
}
int
vlc_cond_timedwait_daytime
(
vlc_cond_t
*
cond
,
vlc_mutex_t
*
mutex
,
time_t
deadline
)
{
struct
timespec
ts
=
{
deadline
,
0
};
return
vlc_cond_timedwait_common
(
cond
,
mutex
,
&
ts
,
pthread_cond_timedwait
);
}
/* pthread */
static
void
clean_detached_thread
(
void
*
data
)
{
struct
vlc_thread
*
th
=
data
;
/* release thread handle */
vlc_mutex_destroy
(
&
th
->
lock
);
vlc_mutex_destroy
(
&
th
->
wait
.
lock
);
free
(
th
);
}
...
...
@@ -344,9 +203,7 @@ static void *detached_thread(void *data)
vlc_cleanup_push
(
clean_detached_thread
,
th
);
th
->
entry
(
th
->
data
);
vlc_cleanup_pop
();
vlc_mutex_destroy
(
&
th
->
lock
);
free
(
th
);
clean_detached_thread
(
th
);
return
NULL
;
}
...
...
@@ -397,10 +254,10 @@ static int vlc_clone_attr (vlc_thread_t *th, void *(*entry) (void *),
vlc_sem_init
(
&
thread
->
finished
,
0
);
atomic_store
(
&
thread
->
killed
,
false
);
thread
->
killable
=
true
;
thread
->
cond
=
NULL
;
thread
->
entry
=
entry
;
thread
->
data
=
data
;
vlc_mutex_init
(
&
thread
->
lock
);
thread
->
wait
.
addr
=
NULL
;
vlc_mutex_init
(
&
thread
->
wait
.
lock
);
pthread_attr_t
attr
;
pthread_attr_init
(
&
attr
);
...
...
@@ -430,8 +287,7 @@ void vlc_join (vlc_thread_t handle, void **result)
int
val
=
pthread_join
(
handle
->
thread
,
result
);
VLC_THREAD_ASSERT
(
"joining thread"
);
vlc_mutex_destroy
(
&
handle
->
lock
);
free
(
handle
);
clean_detached_thread
(
handle
);
}
int
vlc_clone_detach
(
vlc_thread_t
*
th
,
void
*
(
*
entry
)
(
void
*
),
void
*
data
,
...
...
@@ -453,15 +309,18 @@ int vlc_set_priority (vlc_thread_t th, int priority)
void
vlc_cancel
(
vlc_thread_t
thread_id
)
{
pthread_cond_t
*
cond
;
atomic_int
*
addr
;
atomic_store
(
&
thread_id
->
killed
,
true
);
vlc_mutex_lock
(
&
thread_id
->
lock
);
cond
=
thread_id
->
cond
;
if
(
cond
)
pthread_cond_broadcast
(
cond
);
vlc_mutex_unlock
(
&
thread_id
->
lock
);
vlc_mutex_lock
(
&
thread_id
->
wait
.
lock
);
addr
=
thread_id
->
wait
.
addr
;
if
(
addr
!=
NULL
)
{
atomic_fetch_and_explicit
(
addr
,
-
2
,
memory_order_relaxed
);
vlc_addr_broadcast
(
addr
);
}
vlc_mutex_unlock
(
&
thread_id
->
wait
.
lock
);
}
int
vlc_savecancel
(
void
)
...
...
@@ -494,6 +353,43 @@ void vlc_testcancel (void)
pthread_exit
(
NULL
);
}
void
vlc_control_cancel
(
int
cmd
,
...)
{
vlc_thread_t
th
=
vlc_thread_self
();
va_list
ap
;
va_start
(
ap
,
cmd
);
switch
(
cmd
)
{
case
VLC_CANCEL_ADDR_SET
:
{
void
*
addr
=
va_arg
(
ap
,
void
*
);
vlc_mutex_lock
(
&
th
->
wait
.
lock
);
assert
(
th
->
wait
.
addr
==
NULL
);
th
->
wait
.
addr
=
addr
;
vlc_mutex_unlock
(
&
th
->
wait
.
lock
);
break
;
}
case
VLC_CANCEL_ADDR_CLEAR
:
{
void
*
addr
=
va_arg
(
ap
,
void
*
);
vlc_mutex_lock
(
&
th
->
wait
.
lock
);
assert
(
th
->
wait
.
addr
==
addr
);
th
->
wait
.
addr
=
NULL
;
(
void
)
addr
;
vlc_mutex_unlock
(
&
th
->
wait
.
lock
);
break
;
}
default:
vlc_assert_unreachable
();
}
va_end
(
ap
);
}
/* threadvar */
int
vlc_threadvar_create
(
vlc_threadvar_t
*
key
,
void
(
*
destr
)
(
void
*
))
...
...
@@ -527,31 +423,6 @@ mtime_t mdate (void)
return
(
INT64_C
(
1000000
)
*
ts
.
tv_sec
)
+
(
ts
.
tv_nsec
/
1000
);
}
#undef mwait
void
mwait
(
mtime_t
deadline
)
{
vlc_mutex_t
lock
;
vlc_cond_t
wait
;
vlc_mutex_init
(
&
lock
);
vlc_cond_init
(
&
wait
);
vlc_mutex_lock
(
&
lock
);
mutex_cleanup_push
(
&
lock
);
while
(
!
vlc_cond_timedwait
(
&
wait
,
&
lock
,
deadline
));
vlc_cleanup_pop
();
vlc_mutex_unlock
(
&
lock
);
vlc_cond_destroy
(
&
wait
);
vlc_mutex_destroy
(
&
lock
);
}
#undef msleep
void
msleep
(
mtime_t
delay
)
{
mwait
(
mdate
()
+
delay
);
}
/* cpu */
unsigned
vlc_GetCPUCount
(
void
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment