Commit 412dd754 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

threads: add vlc_thread_self() and vlc_thread_id()

parent 42891a74
...@@ -675,6 +675,42 @@ VLC_API void vlc_restorecancel(int state); ...@@ -675,6 +675,42 @@ VLC_API void vlc_restorecancel(int state);
*/ */
VLC_API void vlc_control_cancel(int cmd, ...); VLC_API void vlc_control_cancel(int cmd, ...);
/**
* Thread handle.
*
* This function returns the thread handle of the calling thread.
*
* \note The exact type of the thread handle depends on the platform,
* including an integer type, a pointer type or a compound type of any size.
* If you need an integer identifier, use vlc_thread_id() instead.
*
* \note vlc_join(vlc_thread_self(), NULL) is undefined,
* as it obviously does not make any sense (it might result in a deadlock, but
* there are no warranties that it will).
*
* \return the thread handle
*/
VLC_API vlc_thread_t vlc_thread_self(void) VLC_USED;
/**
* Thread identifier.
*
* This function returns the identifier of the calling thread. The identifier
* cannot change for the entire duration of the thread, and no other thread can
* have the same identifier at the same time in the same process. Typically,
* the identifier is also unique across all running threads of all existing
* processes, but that depends on the operating system.
*
* There are no particular semantics to the thread ID with LibVLC.
* It is provided mainly for tracing and debugging.
*
* \warning This function is not currently implemented on all supported
* platforms. Where not implemented, it returns (unsigned long)-1.
*
* \return the thread identifier (or -1 if unimplemented)
*/
VLC_API unsigned long vlc_thread_id(void) VLC_USED;
/** /**
* Precision monotonic clock. * Precision monotonic clock.
* *
......
...@@ -263,6 +263,7 @@ SOURCES_libvlc_android = \ ...@@ -263,6 +263,7 @@ SOURCES_libvlc_android = \
linux/cpu.c \ linux/cpu.c \
linux/dirs.c \ linux/dirs.c \
android/dirs.c \ android/dirs.c \
linux/thread.c \
android/thread.c \ android/thread.c \
android/error.c \ android/error.c \
posix/filesystem.c \ posix/filesystem.c \
...@@ -281,6 +282,7 @@ SOURCES_libvlc_linux = \ ...@@ -281,6 +282,7 @@ SOURCES_libvlc_linux = \
posix/filesystem.c \ posix/filesystem.c \
posix/netconf.c \ posix/netconf.c \
posix/plugin.c \ posix/plugin.c \
linux/thread.c \
posix/thread.c \ posix/thread.c \
posix/timer.c \ posix/timer.c \
posix/specific.c \ posix/specific.c \
......
...@@ -90,9 +90,9 @@ vlc_thread_fatal (const char *action, int error, ...@@ -90,9 +90,9 @@ vlc_thread_fatal (const char *action, int error,
} }
__android_log_print(ANDROID_LOG_ERROR, "vlc", __android_log_print(ANDROID_LOG_ERROR, "vlc",
"LibVLC fatal error %s (%d) in thread %d " "LibVLC fatal error %s (%d) in thread %lu "
"at %s:%u in %s\n Error message: %s\n", "at %s:%u in %s\n Error message: %s\n",
action, error, syscall (__NR_gettid), file, line, function, msg); action, error, vlc_thread_id (), file, line, function, msg);
abort (); abort ();
} }
...@@ -180,6 +180,16 @@ struct vlc_thread ...@@ -180,6 +180,16 @@ struct vlc_thread
static __thread struct vlc_thread *thread = NULL; static __thread struct vlc_thread *thread = NULL;
vlc_thread_t vlc_thread_self (void)
{
return thread;
}
unsigned long vlc_thread_id (void)
{
return syscall (__NR_gettid);
}
void vlc_threads_setup (libvlc_int_t *p_libvlc) void vlc_threads_setup (libvlc_int_t *p_libvlc)
{ {
(void)p_libvlc; (void)p_libvlc;
......
...@@ -74,13 +74,6 @@ void vlc_trace (const char *fn, const char *file, unsigned line) ...@@ -74,13 +74,6 @@ void vlc_trace (const char *fn, const char *file, unsigned line)
fsync (2); fsync (2);
} }
static inline unsigned long vlc_threadid (void)
{
union { pthread_t th; unsigned long int i; } v = { };
v.th = pthread_self ();
return v.i;
}
#ifndef NDEBUG #ifndef NDEBUG
/* Reports a fatal error from the threading layer, for debugging purposes. */ /* Reports a fatal error from the threading layer, for debugging purposes. */
static void static void
...@@ -89,7 +82,7 @@ vlc_thread_fatal (const char *action, int error, ...@@ -89,7 +82,7 @@ vlc_thread_fatal (const char *action, int error,
{ {
int canc = vlc_savecancel (); int canc = vlc_savecancel ();
fprintf (stderr, "LibVLC fatal error %s (%d) in thread %lu ", fprintf (stderr, "LibVLC fatal error %s (%d) in thread %lu ",
action, error, vlc_threadid ()); action, error, vlc_thread_id ());
vlc_trace (function, file, line); vlc_trace (function, file, line);
char buf[1000]; char buf[1000];
...@@ -463,6 +456,16 @@ int vlc_clone_detach (vlc_thread_t *th, void *(*entry) (void *), void *data, ...@@ -463,6 +456,16 @@ int vlc_clone_detach (vlc_thread_t *th, void *(*entry) (void *), void *data,
return vlc_clone_attr (th, &attr, entry, data, priority); return vlc_clone_attr (th, &attr, entry, data, priority);
} }
vlc_thread_t vlc_thread_self (void)
{
return pthread_self ();
}
unsigned long vlc_thread_id (void)
{
return -1;
}
int vlc_set_priority (vlc_thread_t th, int priority) int vlc_set_priority (vlc_thread_t th, int priority)
{ {
(void) th; (void) priority; (void) th; (void) priority;
......
...@@ -653,6 +653,8 @@ vlc_sdp_Start ...@@ -653,6 +653,8 @@ vlc_sdp_Start
vlc_sd_Start vlc_sd_Start
vlc_sd_Stop vlc_sd_Stop
vlc_testcancel vlc_testcancel
vlc_thread_self
vlc_thread_id
vlc_threadvar_create vlc_threadvar_create
vlc_threadvar_delete vlc_threadvar_delete
vlc_threadvar_get vlc_threadvar_get
......
/*****************************************************************************
* linux/thread.c: Linux specifics for threading
*****************************************************************************
* Copyright (C) 2016 Rémi Denis-Courmont
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
unsigned long vlc_thread_id(void)
{
static __thread pid_t tid = 0;
if (unlikely(tid == 0))
tid = syscall(__NR_gettid);
return tid;
}
...@@ -77,7 +77,7 @@ static ULONG vlc_DosWaitEventSemEx( HEV hev, ULONG ulTimeout ) ...@@ -77,7 +77,7 @@ static ULONG vlc_DosWaitEventSemEx( HEV hev, ULONG ulTimeout )
int n; int n;
ULONG rc; ULONG rc;
struct vlc_thread *th = vlc_threadvar_get( thread_key ); struct vlc_thread *th = vlc_thread_self( thread_key );
if( th == NULL || !th->killable ) if( th == NULL || !th->killable )
{ {
/* Main thread - cannot be cancelled anyway /* Main thread - cannot be cancelled anyway
...@@ -638,6 +638,20 @@ int vlc_set_priority (vlc_thread_t th, int priority) ...@@ -638,6 +638,20 @@ int vlc_set_priority (vlc_thread_t th, int priority)
return VLC_SUCCESS; return VLC_SUCCESS;
} }
vlc_thread_t vlc_thread_self (void)
{
return vlc_threadvar_get (thread_key);
}
unsigned long vlc_thread_id (void)
{
#if 0
return vlc_thread_self ()->tid; /* potential NULL deref */
#else
return -1;
#endif
}
/*** Thread cancellation ***/ /*** Thread cancellation ***/
/* APC procedure for thread cancellation */ /* APC procedure for thread cancellation */
...@@ -659,7 +673,7 @@ int vlc_savecancel (void) ...@@ -659,7 +673,7 @@ int vlc_savecancel (void)
{ {
int state; int state;
struct vlc_thread *th = vlc_threadvar_get (thread_key); struct vlc_thread *th = vlc_thread_self ();
if (th == NULL) if (th == NULL)
return false; /* Main thread - cannot be cancelled anyway */ return false; /* Main thread - cannot be cancelled anyway */
...@@ -670,7 +684,7 @@ int vlc_savecancel (void) ...@@ -670,7 +684,7 @@ int vlc_savecancel (void)
void vlc_restorecancel (int state) void vlc_restorecancel (int state)
{ {
struct vlc_thread *th = vlc_threadvar_get (thread_key); struct vlc_thread *th = vlc_thread_self ();
assert (state == false || state == true); assert (state == false || state == true);
if (th == NULL) if (th == NULL)
...@@ -682,7 +696,7 @@ void vlc_restorecancel (int state) ...@@ -682,7 +696,7 @@ void vlc_restorecancel (int state)
void vlc_testcancel (void) void vlc_testcancel (void)
{ {
struct vlc_thread *th = vlc_threadvar_get (thread_key); struct vlc_thread *th = vlc_thread_self ();
if (th == NULL) if (th == NULL)
return; /* Main thread - cannot be cancelled anyway */ return; /* Main thread - cannot be cancelled anyway */
...@@ -709,7 +723,7 @@ void vlc_control_cancel (int cmd, ...) ...@@ -709,7 +723,7 @@ void vlc_control_cancel (int cmd, ...)
* need to lock anything. */ * need to lock anything. */
va_list ap; va_list ap;
struct vlc_thread *th = vlc_threadvar_get (thread_key); struct vlc_thread *th = vlc_thread_self ();
if (th == NULL) if (th == NULL)
return; /* Main thread - cannot be cancelled anyway */ return; /* Main thread - cannot be cancelled anyway */
...@@ -738,7 +752,7 @@ void vlc_control_cancel (int cmd, ...) ...@@ -738,7 +752,7 @@ void vlc_control_cancel (int cmd, ...)
static int vlc_select( int nfds, fd_set *rdset, fd_set *wrset, fd_set *exset, static int vlc_select( int nfds, fd_set *rdset, fd_set *wrset, fd_set *exset,
struct timeval *timeout ) struct timeval *timeout )
{ {
struct vlc_thread *th = vlc_threadvar_get( thread_key ); struct vlc_thread *th = vlc_thread_self( );
int rc; int rc;
......
...@@ -43,9 +43,6 @@ ...@@ -43,9 +43,6 @@
#include <pthread.h> #include <pthread.h>
#include <sched.h> #include <sched.h>
#ifdef __linux__
# include <sys/syscall.h> /* SYS_gettid */
#endif
#ifdef HAVE_EXECINFO_H #ifdef HAVE_EXECINFO_H
# include <execinfo.h> # include <execinfo.h>
#endif #endif
...@@ -136,20 +133,6 @@ void vlc_trace (const char *fn, const char *file, unsigned line) ...@@ -136,20 +133,6 @@ void vlc_trace (const char *fn, const char *file, unsigned line)
fsync (2); fsync (2);
} }
static inline unsigned long vlc_threadid (void)
{
#if defined (__linux__)
/* glibc does not provide a call for this */
return syscall (__NR_gettid);
#else
union { pthread_t th; unsigned long int i; } v = { };
v.th = pthread_self ();
return v.i;
#endif
}
#ifndef NDEBUG #ifndef NDEBUG
/** /**
* Reports a fatal error from the threading layer, for debugging purposes. * Reports a fatal error from the threading layer, for debugging purposes.
...@@ -160,7 +143,7 @@ vlc_thread_fatal (const char *action, int error, ...@@ -160,7 +143,7 @@ vlc_thread_fatal (const char *action, int error,
{ {
int canc = vlc_savecancel (); int canc = vlc_savecancel ();
fprintf (stderr, "LibVLC fatal error %s (%d) in thread %lu ", fprintf (stderr, "LibVLC fatal error %s (%d) in thread %lu ",
action, error, vlc_threadid ()); action, error, vlc_thread_id ());
vlc_trace (function, file, line); vlc_trace (function, file, line);
perror ("Thread error"); perror ("Thread error");
fflush (stderr); fflush (stderr);
...@@ -563,6 +546,18 @@ int vlc_clone_detach (vlc_thread_t *th, void *(*entry) (void *), void *data, ...@@ -563,6 +546,18 @@ int vlc_clone_detach (vlc_thread_t *th, void *(*entry) (void *), void *data,
return vlc_clone_attr (th, &attr, entry, data, priority); return vlc_clone_attr (th, &attr, entry, data, priority);
} }
vlc_thread_t vlc_thread_self (void)
{
return pthread_self ();
}
#if !defined (__linux__)
unsigned long vlc_thread_id (void)
{
return -1;
}
#endif
int vlc_set_priority (vlc_thread_t th, int priority) int vlc_set_priority (vlc_thread_t th, int priority)
{ {
#if defined (_POSIX_PRIORITY_SCHEDULING) && (_POSIX_PRIORITY_SCHEDULING >= 0) \ #if defined (_POSIX_PRIORITY_SCHEDULING) && (_POSIX_PRIORITY_SCHEDULING >= 0) \
......
...@@ -447,7 +447,7 @@ retry: ...@@ -447,7 +447,7 @@ retry:
#if !IS_INTERRUPTIBLE #if !IS_INTERRUPTIBLE
static bool isCancelled(void) static bool isCancelled(void)
{ {
struct vlc_thread *th = TlsGetValue(thread_key); struct vlc_thread *th = vlc_thread_self();
if (th == NULL) if (th == NULL)
return false; /* Main thread - cannot be cancelled anyway */ return false; /* Main thread - cannot be cancelled anyway */
...@@ -542,6 +542,16 @@ int vlc_clone_detach (vlc_thread_t *p_handle, void *(*entry) (void *), ...@@ -542,6 +542,16 @@ int vlc_clone_detach (vlc_thread_t *p_handle, void *(*entry) (void *),
return vlc_clone_attr (p_handle, true, entry, data, priority); return vlc_clone_attr (p_handle, true, entry, data, priority);
} }
vlc_thread_t vlc_thread_self (void)
{
return TlsGetValue(thread_key);
}
unsigned long vlc_thread_id (void)
{
return GetCurrentThreadId ();
}
int vlc_set_priority (vlc_thread_t th, int priority) int vlc_set_priority (vlc_thread_t th, int priority)
{ {
if (!SetThreadPriority (th->id, priority)) if (!SetThreadPriority (th->id, priority))
...@@ -573,7 +583,7 @@ void vlc_cancel (vlc_thread_t th) ...@@ -573,7 +583,7 @@ void vlc_cancel (vlc_thread_t th)
int vlc_savecancel (void) int vlc_savecancel (void)
{ {
struct vlc_thread *th = TlsGetValue(thread_key); struct vlc_thread *th = vlc_thread_self();
if (th == NULL) if (th == NULL)
return false; /* Main thread - cannot be cancelled anyway */ return false; /* Main thread - cannot be cancelled anyway */
...@@ -584,7 +594,7 @@ int vlc_savecancel (void) ...@@ -584,7 +594,7 @@ int vlc_savecancel (void)
void vlc_restorecancel (int state) void vlc_restorecancel (int state)
{ {
struct vlc_thread *th = TlsGetValue(thread_key); struct vlc_thread *th = vlc_thread_self();
assert (state == false || state == true); assert (state == false || state == true);
if (th == NULL) if (th == NULL)
...@@ -596,7 +606,7 @@ void vlc_restorecancel (int state) ...@@ -596,7 +606,7 @@ void vlc_restorecancel (int state)
void vlc_testcancel (void) void vlc_testcancel (void)
{ {
struct vlc_thread *th = TlsGetValue(thread_key); struct vlc_thread *th = vlc_thread_self();
if (th == NULL) if (th == NULL)
return; /* Main thread - cannot be cancelled anyway */ return; /* Main thread - cannot be cancelled anyway */
if (!th->killable) if (!th->killable)
...@@ -625,7 +635,7 @@ void vlc_control_cancel (int cmd, ...) ...@@ -625,7 +635,7 @@ void vlc_control_cancel (int cmd, ...)
* need to lock anything. */ * need to lock anything. */
va_list ap; va_list ap;
struct vlc_thread *th = TlsGetValue(thread_key); struct vlc_thread *th = vlc_thread_self();
if (th == NULL) if (th == NULL)
return; /* Main thread - cannot be cancelled anyway */ return; /* Main thread - cannot be cancelled anyway */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment