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);
*/
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.
*
......
......@@ -263,6 +263,7 @@ SOURCES_libvlc_android = \
linux/cpu.c \
linux/dirs.c \
android/dirs.c \
linux/thread.c \
android/thread.c \
android/error.c \
posix/filesystem.c \
......@@ -281,6 +282,7 @@ SOURCES_libvlc_linux = \
posix/filesystem.c \
posix/netconf.c \
posix/plugin.c \
linux/thread.c \
posix/thread.c \
posix/timer.c \
posix/specific.c \
......
......@@ -90,9 +90,9 @@ vlc_thread_fatal (const char *action, int error,
}
__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",
action, error, syscall (__NR_gettid), file, line, function, msg);
action, error, vlc_thread_id (), file, line, function, msg);
abort ();
}
......@@ -180,6 +180,16 @@ struct vlc_thread
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)p_libvlc;
......
......@@ -74,13 +74,6 @@ void vlc_trace (const char *fn, const char *file, unsigned line)
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
/* Reports a fatal error from the threading layer, for debugging purposes. */
static void
......@@ -89,7 +82,7 @@ vlc_thread_fatal (const char *action, int error,
{
int canc = vlc_savecancel ();
fprintf (stderr, "LibVLC fatal error %s (%d) in thread %lu ",
action, error, vlc_threadid ());
action, error, vlc_thread_id ());
vlc_trace (function, file, line);
char buf[1000];
......@@ -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);
}
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)
{
(void) th; (void) priority;
......
......@@ -653,6 +653,8 @@ vlc_sdp_Start
vlc_sd_Start
vlc_sd_Stop
vlc_testcancel
vlc_thread_self
vlc_thread_id
vlc_threadvar_create
vlc_threadvar_delete
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 )
int n;
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 )
{
/* Main thread - cannot be cancelled anyway
......@@ -638,6 +638,20 @@ int vlc_set_priority (vlc_thread_t th, int priority)
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 ***/
/* APC procedure for thread cancellation */
......@@ -659,7 +673,7 @@ int vlc_savecancel (void)
{
int state;
struct vlc_thread *th = vlc_threadvar_get (thread_key);
struct vlc_thread *th = vlc_thread_self ();
if (th == NULL)
return false; /* Main thread - cannot be cancelled anyway */
......@@ -670,7 +684,7 @@ int vlc_savecancel (void)
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);
if (th == NULL)
......@@ -682,7 +696,7 @@ void vlc_restorecancel (int state)
void vlc_testcancel (void)
{
struct vlc_thread *th = vlc_threadvar_get (thread_key);
struct vlc_thread *th = vlc_thread_self ();
if (th == NULL)
return; /* Main thread - cannot be cancelled anyway */
......@@ -709,7 +723,7 @@ void vlc_control_cancel (int cmd, ...)
* need to lock anything. */
va_list ap;
struct vlc_thread *th = vlc_threadvar_get (thread_key);
struct vlc_thread *th = vlc_thread_self ();
if (th == NULL)
return; /* Main thread - cannot be cancelled anyway */
......@@ -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,
struct timeval *timeout )
{
struct vlc_thread *th = vlc_threadvar_get( thread_key );
struct vlc_thread *th = vlc_thread_self( );
int rc;
......
......@@ -43,9 +43,6 @@
#include <pthread.h>
#include <sched.h>
#ifdef __linux__
# include <sys/syscall.h> /* SYS_gettid */
#endif
#ifdef HAVE_EXECINFO_H
# include <execinfo.h>
#endif
......@@ -136,20 +133,6 @@ void vlc_trace (const char *fn, const char *file, unsigned line)
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
/**
* Reports a fatal error from the threading layer, for debugging purposes.
......@@ -160,7 +143,7 @@ vlc_thread_fatal (const char *action, int error,
{
int canc = vlc_savecancel ();
fprintf (stderr, "LibVLC fatal error %s (%d) in thread %lu ",
action, error, vlc_threadid ());
action, error, vlc_thread_id ());
vlc_trace (function, file, line);
perror ("Thread error");
fflush (stderr);
......@@ -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);
}
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)
{
#if defined (_POSIX_PRIORITY_SCHEDULING) && (_POSIX_PRIORITY_SCHEDULING >= 0) \
......
......@@ -447,7 +447,7 @@ retry:
#if !IS_INTERRUPTIBLE
static bool isCancelled(void)
{
struct vlc_thread *th = TlsGetValue(thread_key);
struct vlc_thread *th = vlc_thread_self();
if (th == NULL)
return false; /* Main thread - cannot be cancelled anyway */
......@@ -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);
}
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)
{
if (!SetThreadPriority (th->id, priority))
......@@ -573,7 +583,7 @@ void vlc_cancel (vlc_thread_t th)
int vlc_savecancel (void)
{
struct vlc_thread *th = TlsGetValue(thread_key);
struct vlc_thread *th = vlc_thread_self();
if (th == NULL)
return false; /* Main thread - cannot be cancelled anyway */
......@@ -584,7 +594,7 @@ int vlc_savecancel (void)
void vlc_restorecancel (int state)
{
struct vlc_thread *th = TlsGetValue(thread_key);
struct vlc_thread *th = vlc_thread_self();
assert (state == false || state == true);
if (th == NULL)
......@@ -596,7 +606,7 @@ void vlc_restorecancel (int state)
void vlc_testcancel (void)
{
struct vlc_thread *th = TlsGetValue(thread_key);
struct vlc_thread *th = vlc_thread_self();
if (th == NULL)
return; /* Main thread - cannot be cancelled anyway */
if (!th->killable)
......@@ -625,7 +635,7 @@ void vlc_control_cancel (int cmd, ...)
* need to lock anything. */
va_list ap;
struct vlc_thread *th = TlsGetValue(thread_key);
struct vlc_thread *th = vlc_thread_self();
if (th == NULL)
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