From: Vibhav Pant vibhavp@gmail.com
--- include/winnt.h | 100 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-)
diff --git a/include/winnt.h b/include/winnt.h index 55f0c396041..54969557c7f 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -227,6 +227,104 @@ extern "C" { #define __WINE_MALLOC #endif
+/* Thread safety annotations, currently supported by Clang. */ +#define HAVE_THREAD_ANNOTATION_ATTR(a) (defined( __clang__) && __has_attribute(a)) + +#if HAVE_THREAD_ANNOTATION_ATTR(no_thread_safety_analysis) +# define __WINE_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis)) +# else +# define __WINE_NO_THREAD_SAFETY_ANALYSIS +#endif + +/* Used to annotate structs that represent a lockable resource. */ +#if HAVE_THREAD_ANNOTATION_ATTR(capability) +# define __WINE_LOCKABLE(l) __attribute__((capability(l))) +#else +# define __WINE_LOCKABLE(l) +#endif + +/* Used for functions that will acquire the given lock without releasing it + * (i.e, the lock should not be held before the call, and will be held after the function returns). */ +#if HAVE_THREAD_ANNOTATION_ATTR(acquire_capability) +# define __WINE_ACQUIRE(...) __attribute__((acquire_capability(__VA_ARGS__))) +#else +# define __WINE_ACQUIRE(...) +#endif + +/* Used for functions that may acquire the given lock. The first argument should be the value + * returned when a lock was successfully acquired. */ +#if HAVE_THREAD_ANNOTATION_ATTR(try_acquire_capability) +# define __WINE_TRY_ACQUIRE(...) __attribute__((try_acquire_capability(__VA_ARGS__))) +#else +# define __WINE_TRY_ACQUIRE(...) +#endif + +#if HAVE_THREAD_ANNOTATION_ATTR(try_acquire_shared_capability) +# define __WINE_TRY_ACQUIRE_SHARED(...) __attribute__((try_acquire_shared_capability(__VA_ARGS__))) +#else +# define __WINE_TRY_ACQUIRE_SHARED(...) +#endif + +/* Used for functions that will release the given lock. */ +#if HAVE_THREAD_ANNOTATION_ATTR(release_capability) +# define __WINE_RELEASE(...) __attribute__((release_capability(__VA_ARGS__))) +#else +# define __WINE_RELEASE(...) +#endif + +/* The given lock will be held for the duration of the function, and therefore should not be held + * by the caller. */ +#if HAVE_THREAD_ANNOTATION_ATTR(locks_excluded) +# define __WINE_EXCLUDES(...) __attribute__((locks_excluded(__VA_ARGS__))) +#else +# define __WINE_EXCLUDES(...) +#endif + +/* The function requires that the caller hold the given lock. */ +#if HAVE_THREAD_ANNOTATION_ATTR(requires_capability) +# define __WINE_REQUIRES(...) __attribute__((requires_capability(__VA_ARGS__))) +#else +# define __WINE_REQUIRES(...) +#endif + +/* THe function returns the given lock. */ +#if HAVE_THREAD_ANNOTATION_ATTR(lock_returned) +# define __WINE_LOCK_RETURNED(l) __attribute__((lock_returned(l))) +#else +# define __WINE_LOCK_RETURNED(l) +#endif + +/* Access to this variable is guarded by the given lock. */ +#if HAVE_THREAD_ANNOTATION_ATTR(guarded_by) +# define __WINE_GUARDED_BY(l) __attribute__((guarded_by((l)))) +#else +# define __WINE_GUARDED_BY(l) +#endif + +/* Access to the data this pointer points to is guarded by the given lock. + * There's no restriction on the variable itself. */ +#if HAVE_THREAD_ANNOTATION_ATTR(pt_guarded_by) +# define __WINE_PT_GUARDED_BY(l) __attribute__((pt_guarded_by((l)))) +#else +# define __WINE_PT_GUARDED_BY(l) +#endif + +/* (pt_)guarded_by attributes are only currently supported for global variables and non-static class members + * in Clang. These macros allow us to declare (and then define) a dummy stub function for Clang corresponding + * to a struct field containing a lock-able type. Struct fields guarded by that lock should use the + * __WINE_FIELD_(PT_)GUARDED_BY macros. */ +#if HAVE_THREAD_ANNOTATION_ATTR(lock_returned) && HAVE_THREAD_ANNOTATION_ATTR(guarded_by) && HAVE_THREAD_ANNOTATION_ATTR(pt_guarded_by) +# define WINE_DECLARE_LOCK_FIELD_STUB(s, t, f) t *__wine_thread_safety_analysis_stub##s_##f(void *) +# define WINE_DEFINE_LOCK_FIELD_STUB(s, t, f) t *__wine_thread_safety_analysis_stub##s_get_##f(void *__v__) __WINE_LOCK_RETURNED(&((struct s *)__v__)->f) +# define __WINE_FIELD_GUARDED_BY(s, f) __attribute__((guarded_by((__wine_thread_safety_analysis_stub##s_##f)(NULL)))) +# define __WINE_FIELD_PT_GUARDED_BY(s, f) __attribute__((pt_guarded_by((__wine_thread_safety_analysis_stub##s_##f)(NULL)))) +#else +# define WINE_DECLARE_LOCK_FIELD_STUB(s, f) +# define WINE_DEFINE_LOCK_FIELD_STUB(s, f) +# define __WINE_FIELD_GUARDED_BY(s, f) +# define __WINE_FIELD_PT_GUARDED_BY(s, f) +#endif + /* Anonymous union/struct handling */
#ifndef NONAMELESSSTRUCT @@ -6195,7 +6293,7 @@ typedef struct _RTL_CRITICAL_SECTION_DEBUG #endif } RTL_CRITICAL_SECTION_DEBUG, *PRTL_CRITICAL_SECTION_DEBUG, RTL_RESOURCE_DEBUG, *PRTL_RESOURCE_DEBUG;
-typedef struct _RTL_CRITICAL_SECTION { +typedef struct __WINE_LOCKABLE("RTL_CRITICAL_SECTION") _RTL_CRITICAL_SECTION { PRTL_CRITICAL_SECTION_DEBUG DebugInfo; LONG LockCount; LONG RecursionCount;