1
0
mirror of https://github.com/mpv-player/mpv synced 2025-02-17 21:27:08 +00:00
mpv/osdep/threads.c
wm4 cb82cbbbae osdep: add a pthread debugging wrapper
Because pthread failures are virtually undebuggable (which sure is
pretty strange, given all these heavy instrumentation tools these days).

Of course it affects only files which include osdep/threads.h.

I'm departing from the usual way to add symbols with config.h and using
"#if", and defining it on the compiler command line + "#ifdef" because I
don't want to include config.h from a header (which would be necessary
in this case) to keep things slightly cleaner. Maybe this is misguided,
but still.

This would have been easier if mpv defined its own wrappers for all
thread functions. But we don't (which to be honest is probably better
than e.g. going crazy like VLC and essentially reimplementing
everything). This seems to be a good compromise. Since it's off by
default and basically a developer tool, the minor undefined behavior
(redefining reserved symbols) isn't much of an issue.
2020-03-18 22:42:13 +01:00

78 lines
2.4 KiB
C

/*
* This file is part of mpv.
*
* mpv 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.
*
* mpv 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 mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <errno.h>
#include <pthread.h>
#include "common/common.h"
#include "config.h"
#include "threads.h"
#include "timer.h"
int mpthread_mutex_init_recursive(pthread_mutex_t *mutex)
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
int r = pthread_mutex_init(mutex, &attr);
pthread_mutexattr_destroy(&attr);
return r;
}
void mpthread_set_name(const char *name)
{
char tname[80];
snprintf(tname, sizeof(tname), "mpv/%s", name);
#if HAVE_GLIBC_THREAD_NAME
if (pthread_setname_np(pthread_self(), tname) == ERANGE) {
tname[15] = '\0'; // glibc-checked kernel limit
pthread_setname_np(pthread_self(), tname);
}
#elif HAVE_WIN32_INTERNAL_PTHREADS || HAVE_BSD_THREAD_NAME
pthread_set_name_np(pthread_self(), tname);
#elif HAVE_OSX_THREAD_NAME
pthread_setname_np(tname);
#endif
}
int mp_ptwrap_check(const char *file, int line, int res)
{
if (res && res != ETIMEDOUT) {
fprintf(stderr, "%s:%d: internal error: pthread result %d (%s)\n",
file, line, res, mp_strerror(res));
abort();
}
return res;
}
int mp_ptwrap_mutex_init(const char *file, int line, pthread_mutex_t *m,
const pthread_mutexattr_t *attr)
{
pthread_mutexattr_t m_attr;
if (!attr) {
attr = &m_attr;
pthread_mutexattr_init(&m_attr);
// Force normal mutexes to error checking.
pthread_mutexattr_settype(&m_attr, PTHREAD_MUTEX_ERRORCHECK);
}
int res = mp_ptwrap_check(file, line, (pthread_mutex_init)(m, attr));
if (attr == &m_attr)
pthread_mutexattr_destroy(&m_attr);
return res;
}