Module: wine Branch: stable Commit: 9e5541cbfb0c12f16a531ae2f45a111e579227ff URL: https://source.winehq.org/git/wine.git/?a=commit;h=9e5541cbfb0c12f16a531ae2f...
Author: Piotr Caban piotr@codeweavers.com Date: Tue Mar 26 18:12:13 2019 +0100
msvcp90: Add support for more creation flags in _Mtx class.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46908 Signed-off-by: Piotr Caban piotr@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org (cherry picked from commit 8a82912b28aa0c0c3ac4fc309fa8079e4415111d) Signed-off-by: Michael Stefaniuc mstefani@winehq.org
---
dlls/msvcp120/tests/msvcp120.c | 44 ++++++++++++++++++++++++++++++++++++++++++ dlls/msvcp90/misc.c | 13 +++++++++---- 2 files changed, 53 insertions(+), 4 deletions(-)
diff --git a/dlls/msvcp120/tests/msvcp120.c b/dlls/msvcp120/tests/msvcp120.c index ac38aa6..7bf0237 100644 --- a/dlls/msvcp120/tests/msvcp120.c +++ b/dlls/msvcp120/tests/msvcp120.c @@ -323,6 +323,10 @@ typedef struct void *tail; } critical_section;
+#define MTX_PLAIN 0x1 +#define MTX_TRY 0x2 +#define MTX_TIMED 0x4 +#define MTX_RECURSIVE 0x100 typedef struct { DWORD flags; @@ -335,6 +339,7 @@ static int (__cdecl *p__Mtx_init)(_Mtx_t*, int); static void (__cdecl *p__Mtx_destroy)(_Mtx_t*); static int (__cdecl *p__Mtx_lock)(_Mtx_t*); static int (__cdecl *p__Mtx_unlock)(_Mtx_t*); +static int (__cdecl *p__Mtx_trylock)(_Mtx_t*);
/* cnd */ typedef void *_Cnd_t; @@ -801,6 +806,8 @@ static BOOL init(void) "_Mtx_lock"); SET(p__Mtx_unlock, "_Mtx_unlock"); + SET(p__Mtx_trylock, + "_Mtx_trylock");
SET(p__Cnd_init, "_Cnd_init"); @@ -2440,6 +2447,42 @@ static void test__Pad(void) CloseHandle(_Pad__Launch_returned); }
+static void test__Mtx(void) +{ +# + static int flags[] = + { + 0, MTX_PLAIN, MTX_TRY, MTX_TIMED, MTX_RECURSIVE, + MTX_PLAIN|MTX_TRY, MTX_PLAIN|MTX_RECURSIVE, MTX_PLAIN|0xbeef + }; + _Mtx_t mtx; + int i, r, expect; + + for (i=0; i<ARRAY_SIZE(flags); i++) + { + if (flags[i] == MTX_PLAIN || flags[i] & MTX_RECURSIVE) + expect = 0; + else + expect = 3; + + r = p__Mtx_init(&mtx, flags[i]); + ok(!r, "failed to init mtx (flags %x)\n", flags[i]); + + r = p__Mtx_trylock(&mtx); + ok(!r, "_Mtx_trylock returned %x (flags %x)\n", r, flags[i]); + r = p__Mtx_trylock(&mtx); + ok(r == expect, "_Mtx_trylock returned %x (flags %x)\n", r, flags[i]); + if(!r) p__Mtx_unlock(&mtx); + + r = p__Mtx_lock(&mtx); + ok(r == expect, "_Mtx_lock returned %x (flags %x)\n", r, flags[i]); + if(!r) p__Mtx_unlock(&mtx); + + p__Mtx_unlock(&mtx); + p__Mtx_destroy(&mtx); + } +} + static void test_threads__Mtx(void) { void *mtx = NULL; @@ -3343,6 +3386,7 @@ START_TEST(msvcp120) test_thrd(); test_cnd(); test__Pad(); + test__Mtx(); test_threads__Mtx();
test_vector_base_v4__Segment_index_of(); diff --git a/dlls/msvcp90/misc.c b/dlls/msvcp90/misc.c index 0e81b8d..dac6a96 100644 --- a/dlls/msvcp90/misc.c +++ b/dlls/msvcp90/misc.c @@ -681,7 +681,10 @@ __ASM_GLOBAL_FUNC(call_thiscall_func,
#endif /* __i386__ */
-#define MTX_MULTI_LOCK 0x100 +#define MTX_PLAIN 0x1 +#define MTX_TRY 0x2 +#define MTX_TIMED 0x4 +#define MTX_RECURSIVE 0x100 #define MTX_LOCKED 3 typedef struct { @@ -703,7 +706,7 @@ typedef _Mtx_t *_Mtx_arg_t;
void __cdecl _Mtx_init_in_situ(_Mtx_t mtx, int flags) { - if(flags & ~MTX_MULTI_LOCK) + if(flags & ~(MTX_PLAIN | MTX_TRY | MTX_TIMED | MTX_RECURSIVE)) FIXME("unknown flags ignored: %x\n", flags);
mtx->flags = flags; @@ -740,7 +743,8 @@ int __cdecl _Mtx_lock(_Mtx_arg_t mtx) if(MTX_T_FROM_ARG(mtx)->thread_id != GetCurrentThreadId()) { call_func1(critical_section_lock, &MTX_T_FROM_ARG(mtx)->cs); MTX_T_FROM_ARG(mtx)->thread_id = GetCurrentThreadId(); - }else if(!(MTX_T_FROM_ARG(mtx)->flags & MTX_MULTI_LOCK)) { + }else if(!(MTX_T_FROM_ARG(mtx)->flags & MTX_RECURSIVE) + && MTX_T_FROM_ARG(mtx)->flags != MTX_PLAIN) { return MTX_LOCKED; }
@@ -764,7 +768,8 @@ int __cdecl _Mtx_trylock(_Mtx_arg_t mtx) if(!call_func1(critical_section_trylock, &MTX_T_FROM_ARG(mtx)->cs)) return MTX_LOCKED; MTX_T_FROM_ARG(mtx)->thread_id = GetCurrentThreadId(); - }else if(!(MTX_T_FROM_ARG(mtx)->flags & MTX_MULTI_LOCK)) { + }else if(!(MTX_T_FROM_ARG(mtx)->flags & MTX_RECURSIVE) + && MTX_T_FROM_ARG(mtx)->flags != MTX_PLAIN) { return MTX_LOCKED; }