15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * libusbx synchronization using POSIX Threads
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
4ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * Copyright © 2011 Vitali Lovich <vlovich@aliph.com>
5ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * Copyright © 2011 Peter Stuge <peter@stuge.se>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This library is free software; you can redistribute it and/or
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * modify it under the terms of the GNU Lesser General Public
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * License as published by the Free Software Foundation; either
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * version 2.1 of the License, or (at your option) any later version.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This library is distributed in the hope that it will be useful,
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Lesser General Public License for more details.
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * You should have received a copy of the GNU Lesser General Public
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * License along with this library; if not, write to the Free Software
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#if defined(__linux__) || defined(__OpenBSD__)
23ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch# include <unistd.h>
24ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch# include <sys/syscall.h>
25ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#elif defined(__APPLE__)
26ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch# include <mach/mach.h>
27ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#elif defined(__CYGWIN__)
28ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch# include <windows.h>
29ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "threads_posix.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int usbi_mutex_init_recursive(pthread_mutex_t *mutex, pthread_mutexattr_t *attr)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int err;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pthread_mutexattr_t stack_attr;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!attr) {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		attr = &stack_attr;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		err = pthread_mutexattr_init(&stack_attr);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (err != 0)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return err;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch	/* mutexattr_settype requires _GNU_SOURCE or _XOPEN_SOURCE >= 500 on Linux */
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	err = pthread_mutexattr_settype(attr, PTHREAD_MUTEX_RECURSIVE);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (err != 0)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto finish;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	err = pthread_mutex_init(mutex, attr);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)finish:
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (attr == &stack_attr)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		pthread_mutexattr_destroy(&stack_attr);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return err;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
57ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
58ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochint usbi_get_tid(void)
59ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch{
60ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch	int ret = -1;
61ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#if defined(__linux__)
62ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch	ret = syscall(SYS_gettid);
63ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#elif defined(__OpenBSD__)
64ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch	/* The following only works with OpenBSD > 5.1 as it requires
65ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch	   real thread support. For 5.1 and earlier, -1 is returned. */
66ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch	ret = syscall(SYS_getthrid);
67ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#elif defined(__APPLE__)
68ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch	ret = mach_thread_self();
69ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch	mach_port_deallocate(mach_task_self(), ret);
70ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#elif defined(__CYGWIN__)
71ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch	ret = GetCurrentThreadId();
72ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif
73ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch/* TODO: NetBSD thread ID support */
74ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch	return ret;
75ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
76