Based on !2524.
This adds the remaining stubs needed for Crazy Machines 3 to work and decode preview images correctly in online mode.
-- v4: msvcr110: Implement _Context::_IsSynchronouslyBlocked. msvcr110: Add _Context::_IsSynchronouslyBlocked stub. msvcr110: Add _Cancellation_beacon::_Cancellation_beacon_dtor stub. msvcr110: Add _Cancellation_beacon::_Cancellation_beacon_ctor stub.
From: Torge Matthies tmatthies@codeweavers.com
The pointer is needed for Crazy Machines 3 to not crash.
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/msvcr110/msvcr110.spec | 2 +- dlls/msvcr120/msvcr120.spec | 2 +- dlls/msvcr120_app/msvcr120_app.spec | 2 +- dlls/msvcrt/concurrency.c | 19 +++++++++++++++++++ 4 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec index 1032c9e4c7a..7d8b32da0ab 100644 --- a/dlls/msvcr110/msvcr110.spec +++ b/dlls/msvcr110/msvcr110.spec @@ -19,7 +19,7 @@ @ stub -arch=win64 ??0_CancellationTokenState@details@Concurrency@@AEAA@XZ @ stub -arch=arm ??0_Cancellation_beacon@details@Concurrency@@QAA@XZ @ stub -arch=i386 ??0_Cancellation_beacon@details@Concurrency@@QAE@XZ -@ stub -arch=win64 ??0_Cancellation_beacon@details@Concurrency@@QEAA@XZ +@ cdecl -arch=win64 ??0_Cancellation_beacon@details@Concurrency@@QEAA@XZ(ptr) _Cancellation_beacon_ctor @ cdecl -arch=arm ??0_Condition_variable@details@Concurrency@@QAA@XZ(ptr) _Condition_variable_ctor @ thiscall -arch=i386 ??0_Condition_variable@details@Concurrency@@QAE@XZ(ptr) _Condition_variable_ctor @ cdecl -arch=win64 ??0_Condition_variable@details@Concurrency@@QEAA@XZ(ptr) _Condition_variable_ctor diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index ca11ea4b49d..6e2bda818a7 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -16,7 +16,7 @@ @ cdecl -arch=win64 ??0SchedulerPolicy@Concurrency@@QEAA@XZ(ptr) SchedulerPolicy_ctor @ stub -arch=arm ??0_Cancellation_beacon@details@Concurrency@@QAA@XZ @ stub -arch=i386 ??0_Cancellation_beacon@details@Concurrency@@QAE@XZ -@ stub -arch=win64 ??0_Cancellation_beacon@details@Concurrency@@QEAA@XZ +@ cdecl -arch=win64 ??0_Cancellation_beacon@details@Concurrency@@QEAA@XZ(ptr) _Cancellation_beacon_ctor @ cdecl -arch=arm ??0_Condition_variable@details@Concurrency@@QAA@XZ(ptr) _Condition_variable_ctor @ thiscall -arch=i386 ??0_Condition_variable@details@Concurrency@@QAE@XZ(ptr) _Condition_variable_ctor @ cdecl -arch=win64 ??0_Condition_variable@details@Concurrency@@QEAA@XZ(ptr) _Condition_variable_ctor diff --git a/dlls/msvcr120_app/msvcr120_app.spec b/dlls/msvcr120_app/msvcr120_app.spec index aad6ece8acc..e715076eb4f 100644 --- a/dlls/msvcr120_app/msvcr120_app.spec +++ b/dlls/msvcr120_app/msvcr120_app.spec @@ -14,7 +14,7 @@ @ cdecl -arch=win64 ??0SchedulerPolicy@Concurrency@@QEAA@XZ(ptr) msvcr120.??0SchedulerPolicy@Concurrency@@QEAA@XZ @ stub -arch=arm ??0_Cancellation_beacon@details@Concurrency@@QAA@XZ @ stub -arch=i386 ??0_Cancellation_beacon@details@Concurrency@@QAE@XZ -@ stub -arch=win64 ??0_Cancellation_beacon@details@Concurrency@@QEAA@XZ +@ cdecl -arch=win64 ??0_Cancellation_beacon@details@Concurrency@@QEAA@XZ(ptr) msvcr120.??0_Cancellation_beacon@details@Concurrency@@QEAA@XZ @ cdecl -arch=arm ??0_Condition_variable@details@Concurrency@@QAA@XZ(ptr) msvcr120.??0_Condition_variable@details@Concurrency@@QAA@XZ @ thiscall -arch=i386 ??0_Condition_variable@details@Concurrency@@QAE@XZ(ptr) msvcr120.??0_Condition_variable@details@Concurrency@@QAE@XZ @ cdecl -arch=win64 ??0_Condition_variable@details@Concurrency@@QEAA@XZ(ptr) msvcr120.??0_Condition_variable@details@Concurrency@@QEAA@XZ diff --git a/dlls/msvcrt/concurrency.c b/dlls/msvcrt/concurrency.c index d148aadd13a..a88ca7feda9 100644 --- a/dlls/msvcrt/concurrency.c +++ b/dlls/msvcrt/concurrency.c @@ -309,6 +309,10 @@ typedef struct cv_queue { LONG expired; } cv_queue;
+typedef struct { + void *unknown; +} _Cancellation_beacon; + typedef struct { /* cv_queue structure is not binary compatible */ cv_queue *queue; @@ -2860,6 +2864,21 @@ int __cdecl event_wait_for_multiple(event **events, size_t count, bool wait_all,
#if _MSVCR_VER >= 110
+struct { + void *unk; +} _Cancellation_beacon_unknown = { + 0x0 +}; + +/* ??0_Cancellation_beacon@details@Concurrency@@QEAA@XZ */ +DEFINE_THISCALL_WRAPPER(_Cancellation_beacon_ctor, 4) +_Cancellation_beacon* __thiscall _Cancellation_beacon_ctor(_Cancellation_beacon *this) +{ + FIXME("(%p): stub!\n", this); + this->unknown = &_Cancellation_beacon_unknown; + return this; +} + /* ??0_Condition_variable@details@Concurrency@@QAE@XZ */ /* ??0_Condition_variable@details@Concurrency@@QEAA@XZ */ DEFINE_THISCALL_WRAPPER(_Condition_variable_ctor, 4)
From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/msvcr110/msvcr110.spec | 2 +- dlls/msvcr120/msvcr120.spec | 2 +- dlls/msvcr120_app/msvcr120_app.spec | 2 +- dlls/msvcrt/concurrency.c | 7 +++++++ 4 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec index 7d8b32da0ab..9589f5bfb95 100644 --- a/dlls/msvcr110/msvcr110.spec +++ b/dlls/msvcr110/msvcr110.spec @@ -277,7 +277,7 @@ @ stub -arch=win64 ??1_CancellationTokenState@details@Concurrency@@UEAA@XZ @ stub -arch=arm ??1_Cancellation_beacon@details@Concurrency@@QAA@XZ @ stub -arch=i386 ??1_Cancellation_beacon@details@Concurrency@@QAE@XZ -@ stub -arch=win64 ??1_Cancellation_beacon@details@Concurrency@@QEAA@XZ +@ cdecl -arch=win64 ??1_Cancellation_beacon@details@Concurrency@@QEAA@XZ(ptr) _Cancellation_beacon_dtor @ cdecl -arch=arm ??1_Condition_variable@details@Concurrency@@QAA@XZ(ptr) _Condition_variable_dtor @ thiscall -arch=i386 ??1_Condition_variable@details@Concurrency@@QAE@XZ(ptr) _Condition_variable_dtor @ cdecl -arch=win64 ??1_Condition_variable@details@Concurrency@@QEAA@XZ(ptr) _Condition_variable_dtor diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index 6e2bda818a7..5b7ab406206 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -271,7 +271,7 @@ @ cdecl -arch=win64 ??1SchedulerPolicy@Concurrency@@QEAA@XZ(ptr) SchedulerPolicy_dtor @ stub -arch=arm ??1_Cancellation_beacon@details@Concurrency@@QAA@XZ @ stub -arch=i386 ??1_Cancellation_beacon@details@Concurrency@@QAE@XZ -@ stub -arch=win64 ??1_Cancellation_beacon@details@Concurrency@@QEAA@XZ +@ cdecl -arch=win64 ??1_Cancellation_beacon@details@Concurrency@@QEAA@XZ(ptr) _Cancellation_beacon_dtor @ cdecl -arch=arm ??1_Condition_variable@details@Concurrency@@QAA@XZ(ptr) _Condition_variable_dtor @ thiscall -arch=i386 ??1_Condition_variable@details@Concurrency@@QAE@XZ(ptr) _Condition_variable_dtor @ cdecl -arch=win64 ??1_Condition_variable@details@Concurrency@@QEAA@XZ(ptr) _Condition_variable_dtor diff --git a/dlls/msvcr120_app/msvcr120_app.spec b/dlls/msvcr120_app/msvcr120_app.spec index e715076eb4f..b59f78cbde2 100644 --- a/dlls/msvcr120_app/msvcr120_app.spec +++ b/dlls/msvcr120_app/msvcr120_app.spec @@ -269,7 +269,7 @@ @ cdecl -arch=win64 ??1SchedulerPolicy@Concurrency@@QEAA@XZ(ptr) msvcr120.??1SchedulerPolicy@Concurrency@@QEAA@XZ @ stub -arch=arm ??1_Cancellation_beacon@details@Concurrency@@QAA@XZ @ stub -arch=i386 ??1_Cancellation_beacon@details@Concurrency@@QAE@XZ -@ stub -arch=win64 ??1_Cancellation_beacon@details@Concurrency@@QEAA@XZ +@ cdecl -arch=win64 ??1_Cancellation_beacon@details@Concurrency@@QEAA@XZ(ptr) msvcr120.??1_Cancellation_beacon@details@Concurrency@@QEAA@XZ @ cdecl -arch=arm ??1_Condition_variable@details@Concurrency@@QAA@XZ(ptr) msvcr120.??1_Condition_variable@details@Concurrency@@QAA@XZ @ thiscall -arch=i386 ??1_Condition_variable@details@Concurrency@@QAE@XZ(ptr) msvcr120.??1_Condition_variable@details@Concurrency@@QAE@XZ @ cdecl -arch=win64 ??1_Condition_variable@details@Concurrency@@QEAA@XZ(ptr) msvcr120.??1_Condition_variable@details@Concurrency@@QEAA@XZ diff --git a/dlls/msvcrt/concurrency.c b/dlls/msvcrt/concurrency.c index a88ca7feda9..da29f478b1a 100644 --- a/dlls/msvcrt/concurrency.c +++ b/dlls/msvcrt/concurrency.c @@ -2879,6 +2879,13 @@ _Cancellation_beacon* __thiscall _Cancellation_beacon_ctor(_Cancellation_beacon return this; }
+/* ??1_Cancellation_beacon@details@Concurrency@@QEAA@XZ */ +DEFINE_THISCALL_WRAPPER(_Cancellation_beacon_dtor, 4) +void __thiscall _Cancellation_beacon_dtor(_Cancellation_beacon *this) +{ + FIXME("(%p): stub!\n", this); +} + /* ??0_Condition_variable@details@Concurrency@@QAE@XZ */ /* ??0_Condition_variable@details@Concurrency@@QEAA@XZ */ DEFINE_THISCALL_WRAPPER(_Condition_variable_ctor, 4)
From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/msvcr110/msvcr110.spec | 6 +++--- dlls/msvcr120/msvcr120.spec | 6 +++--- dlls/msvcr120_app/msvcr120_app.spec | 6 +++--- dlls/msvcrt/concurrency.c | 7 +++++++ 4 files changed, 16 insertions(+), 9 deletions(-)
diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec index 9589f5bfb95..f9f4a2dc9a7 100644 --- a/dlls/msvcr110/msvcr110.spec +++ b/dlls/msvcr110/msvcr110.spec @@ -550,9 +550,9 @@ @ stub -arch=arm ?_IsCanceling@_TaskCollection@details@Concurrency@@QAA_NXZ @ stub -arch=i386 ?_IsCanceling@_TaskCollection@details@Concurrency@@QAE_NXZ @ stub -arch=win64 ?_IsCanceling@_TaskCollection@details@Concurrency@@QEAA_NXZ -@ stub -arch=arm ?_IsSynchronouslyBlocked@_Context@details@Concurrency@@QBA_NXZ -@ stub -arch=i386 ?_IsSynchronouslyBlocked@_Context@details@Concurrency@@QBE_NXZ -@ stub -arch=win64 ?_IsSynchronouslyBlocked@_Context@details@Concurrency@@QEBA_NXZ +@ cdecl -arch=arm ?_IsSynchronouslyBlocked@_Context@details@Concurrency@@QBA_NXZ(ptr) _Context_IsSynchronouslyBlocked +@ thiscall -arch=i386 ?_IsSynchronouslyBlocked@_Context@details@Concurrency@@QBE_NXZ(ptr) _Context_IsSynchronouslyBlocked +@ cdecl -arch=win64 ?_IsSynchronouslyBlocked@_Context@details@Concurrency@@QEBA_NXZ(ptr) _Context_IsSynchronouslyBlocked @ stub -arch=win32 ?_Name_base@type_info@@CAPBDPBV1@PAU__type_info_node@@@Z @ stub -arch=win64 ?_Name_base@type_info@@CAPEBDPEBV1@PEAU__type_info_node@@@Z @ stub -arch=win32 ?_Name_base_internal@type_info@@CAPBDPBV1@PAU__type_info_node@@@Z diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index 5b7ab406206..768eca16d3c 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -541,9 +541,9 @@ @ stub -arch=arm ?_IsCanceling@_TaskCollection@details@Concurrency@@QAA_NXZ @ stub -arch=i386 ?_IsCanceling@_TaskCollection@details@Concurrency@@QAE_NXZ @ stub -arch=win64 ?_IsCanceling@_TaskCollection@details@Concurrency@@QEAA_NXZ -@ stub -arch=arm ?_IsSynchronouslyBlocked@_Context@details@Concurrency@@QBA_NXZ -@ stub -arch=i386 ?_IsSynchronouslyBlocked@_Context@details@Concurrency@@QBE_NXZ -@ stub -arch=win64 ?_IsSynchronouslyBlocked@_Context@details@Concurrency@@QEBA_NXZ +@ cdecl -arch=arm ?_IsSynchronouslyBlocked@_Context@details@Concurrency@@QBA_NXZ(ptr) _Context_IsSynchronouslyBlocked +@ thiscall -arch=i386 ?_IsSynchronouslyBlocked@_Context@details@Concurrency@@QBE_NXZ(ptr) _Context_IsSynchronouslyBlocked +@ cdecl -arch=win64 ?_IsSynchronouslyBlocked@_Context@details@Concurrency@@QEBA_NXZ(ptr) _Context_IsSynchronouslyBlocked @ stub -arch=win32 ?_Name_base@type_info@@CAPBDPBV1@PAU__type_info_node@@@Z @ stub -arch=win64 ?_Name_base@type_info@@CAPEBDPEBV1@PEAU__type_info_node@@@Z @ stub -arch=win32 ?_Name_base_internal@type_info@@CAPBDPBV1@PAU__type_info_node@@@Z diff --git a/dlls/msvcr120_app/msvcr120_app.spec b/dlls/msvcr120_app/msvcr120_app.spec index b59f78cbde2..641612af822 100644 --- a/dlls/msvcr120_app/msvcr120_app.spec +++ b/dlls/msvcr120_app/msvcr120_app.spec @@ -538,9 +538,9 @@ @ stub -arch=arm ?_IsCanceling@_TaskCollection@details@Concurrency@@QAA_NXZ @ stub -arch=i386 ?_IsCanceling@_TaskCollection@details@Concurrency@@QAE_NXZ @ stub -arch=win64 ?_IsCanceling@_TaskCollection@details@Concurrency@@QEAA_NXZ -@ stub -arch=arm ?_IsSynchronouslyBlocked@_Context@details@Concurrency@@QBA_NXZ -@ stub -arch=i386 ?_IsSynchronouslyBlocked@_Context@details@Concurrency@@QBE_NXZ -@ stub -arch=win64 ?_IsSynchronouslyBlocked@_Context@details@Concurrency@@QEBA_NXZ +@ cdecl -arch=arm ?_IsSynchronouslyBlocked@_Context@details@Concurrency@@QBA_NXZ(ptr) msvcr120.?_IsSynchronouslyBlocked@_Context@details@Concurrency@@QBA_NXZ +@ thiscall -arch=i386 ?_IsSynchronouslyBlocked@_Context@details@Concurrency@@QBE_NXZ(ptr) msvcr120.?_IsSynchronouslyBlocked@_Context@details@Concurrency@@QBE_NXZ +@ cdecl -arch=win64 ?_IsSynchronouslyBlocked@_Context@details@Concurrency@@QEBA_NXZ(ptr) msvcr120.?_IsSynchronouslyBlocked@_Context@details@Concurrency@@QEBA_NXZ @ stub -arch=win32 ?_Name_base@type_info@@CAPBDPBV1@PAU__type_info_node@@@Z @ stub -arch=win64 ?_Name_base@type_info@@CAPEBDPEBV1@PEAU__type_info_node@@@Z @ stub -arch=win32 ?_Name_base_internal@type_info@@CAPBDPBV1@PAU__type_info_node@@@Z diff --git a/dlls/msvcrt/concurrency.c b/dlls/msvcrt/concurrency.c index da29f478b1a..8388150e6f7 100644 --- a/dlls/msvcrt/concurrency.c +++ b/dlls/msvcrt/concurrency.c @@ -879,6 +879,13 @@ _Context *__cdecl _Context__CurrentContext(_Context *ret) ret->context = Context_CurrentContext(); return ret; } + +DEFINE_THISCALL_WRAPPER(_Context_IsSynchronouslyBlocked, 4) +BOOL __thiscall _Context_IsSynchronouslyBlocked(const _Context *this) +{ + TRACE("(%p)\n", this); + return FALSE; +} #endif
DEFINE_THISCALL_WRAPPER(ExternalContextBase_GetId, 4)
From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/msvcrt/concurrency.c | 225 +++++++++++++++++++++++++------------- 1 file changed, 150 insertions(+), 75 deletions(-)
diff --git a/dlls/msvcrt/concurrency.c b/dlls/msvcrt/concurrency.c index 8388150e6f7..4132db1de8e 100644 --- a/dlls/msvcrt/concurrency.c +++ b/dlls/msvcrt/concurrency.c @@ -68,6 +68,8 @@ typedef struct { unsigned int, (const Context*), (this)) #define call_Context_GetScheduleGroupId(this) CALL_VTBL_FUNC(this, 8, \ unsigned int, (const Context*), (this)) +#define call_Context_IsSynchronouslyBlocked(this) CALL_VTBL_FUNC(this, 12, \ + bool, (const Context*), (this)) #define call_Context_dtor(this, flags) CALL_VTBL_FUNC(this, 20, \ Context*, (Context*, unsigned int), (this, flags))
@@ -96,6 +98,7 @@ typedef struct { struct scheduler_list scheduler; unsigned int id; union allocator_cache_entry *allocator_cache[8]; + BOOL sync_blocked; } ExternalContextBase; extern const vtable_ptr ExternalContextBase_vtable; static void ExternalContextBase_ctor(ExternalContextBase*); @@ -884,7 +887,7 @@ DEFINE_THISCALL_WRAPPER(_Context_IsSynchronouslyBlocked, 4) BOOL __thiscall _Context_IsSynchronouslyBlocked(const _Context *this) { TRACE("(%p)\n", this); - return FALSE; + return call_Context_IsSynchronouslyBlocked(this->context); } #endif
@@ -919,7 +922,7 @@ DEFINE_THISCALL_WRAPPER(ExternalContextBase_IsSynchronouslyBlocked, 4) bool __thiscall ExternalContextBase_IsSynchronouslyBlocked(const ExternalContextBase *this) { FIXME("(%p)->() stub\n", this); - return FALSE; + return this->sync_blocked; }
static void remove_scheduled_chores(Scheduler *scheduler, const ExternalContextBase *context) @@ -995,6 +998,7 @@ static void ExternalContextBase_ctor(ExternalContextBase *this) memset(this, 0, sizeof(*this)); this->context.vtable = &ExternalContextBase_vtable; this->id = InterlockedIncrement(&context_id); + this->sync_blocked = FALSE;
create_default_scheduler(); this->scheduler.scheduler = &default_scheduler->scheduler; @@ -2232,6 +2236,31 @@ void __thiscall _StructuredTaskCollection__Schedule( } }
+static inline void context_sync_block(Context *ctx) +{ + ExternalContextBase *context = (ExternalContextBase*)ctx; + if (context->context.vtable == &ExternalContextBase_vtable) + context->sync_blocked = TRUE; +} + +static void CALLBACK context_sync_unblock(BOOL normal, void *data) +{ + ExternalContextBase *context = data; + if (context->context.vtable == &ExternalContextBase_vtable) + context->sync_blocked = FALSE; +} + +#define SYNCHRONOUSLY_BLOCKED_START(ctx) \ + do { Context *__ctx = (Context*)(ctx); \ + __TRY { \ + context_sync_block(__ctx); \ + do { + +#define SYNCHRONOUSLY_BLOCKED_END() \ + } while (0); \ + } __FINALLY_CTX(context_sync_unblock, __ctx) \ + } while (0) + static void CALLBACK exception_ptr_rethrow_finally(BOOL normal, void *data) { exception_ptr *ep = data; @@ -2270,9 +2299,11 @@ _TaskCollectionStatus __stdcall _StructuredTaskCollection__RunAndWait( } }
- expected = this->count ? this->count : FINISHED_INITIAL; - while ((val = this->finished) != expected) - RtlWaitOnAddress((LONG*)&this->finished, &val, sizeof(val), NULL); + SYNCHRONOUSLY_BLOCKED_START(get_current_context()) { + expected = this->count ? this->count : FINISHED_INITIAL; + while ((val = this->finished) != expected) + RtlWaitOnAddress((LONG*)&this->finished, &val, sizeof(val), NULL); + } SYNCHRONOUSLY_BLOCKED_END();
this->finished = 0; this->count = 0; @@ -2378,12 +2409,16 @@ static inline void cs_lock(critical_section *cs, cs_queue *q) last = InterlockedExchangePointer(&cs->tail, q); if(last) { last->next = q; - NtWaitForKeyedEvent(keyed_event, q, 0, NULL); + SYNCHRONOUSLY_BLOCKED_START(get_current_context()) { + NtWaitForKeyedEvent(keyed_event, q, 0, NULL); + } SYNCHRONOUSLY_BLOCKED_END(); }
cs_set_head(cs, q); if(InterlockedCompareExchangePointer(&cs->tail, &cs->unk_active, q) != q) { - spin_wait_for_next_cs(q); + SYNCHRONOUSLY_BLOCKED_START(get_current_context()) { + spin_wait_for_next_cs(q); + } SYNCHRONOUSLY_BLOCKED_END(); cs->unk_active.next = q->next; } } @@ -2415,7 +2450,9 @@ bool __thiscall critical_section_try_lock(critical_section *this) if(!InterlockedCompareExchangePointer(&this->tail, &q, NULL)) { cs_set_head(this, &q); if(InterlockedCompareExchangePointer(&this->tail, &this->unk_active, &q) != &q) { - spin_wait_for_next_cs(&q); + SYNCHRONOUSLY_BLOCKED_START(get_current_context()) { + spin_wait_for_next_cs(&q); + } SYNCHRONOUSLY_BLOCKED_END(); this->unk_active.next = q.next; } return TRUE; @@ -2428,34 +2465,40 @@ bool __thiscall critical_section_try_lock(critical_section *this) DEFINE_THISCALL_WRAPPER(critical_section_unlock, 4) void __thiscall critical_section_unlock(critical_section *this) { + BOOL skip_release = FALSE; + TRACE("(%p)\n", this);
this->unk_thread_id = 0; this->head = NULL; if(InterlockedCompareExchangePointer(&this->tail, NULL, &this->unk_active) == &this->unk_active) return; - spin_wait_for_next_cs(&this->unk_active); + SYNCHRONOUSLY_BLOCKED_START(get_current_context()) { + spin_wait_for_next_cs(&this->unk_active);
#if _MSVCR_VER >= 110 - while(1) { - cs_queue *next; + while(1) { + cs_queue *next;
- if(!InterlockedExchange(&this->unk_active.next->free, TRUE)) - break; + if(!InterlockedExchange(&this->unk_active.next->free, TRUE)) + break; + + next = this->unk_active.next; + if(InterlockedCompareExchangePointer(&this->tail, NULL, next) == next) { + HeapFree(GetProcessHeap(), 0, next); + skip_release = TRUE; + break; + } + spin_wait_for_next_cs(next);
- next = this->unk_active.next; - if(InterlockedCompareExchangePointer(&this->tail, NULL, next) == next) { + this->unk_active.next = next->next; HeapFree(GetProcessHeap(), 0, next); - return; } - spin_wait_for_next_cs(next); - - this->unk_active.next = next->next; - HeapFree(GetProcessHeap(), 0, next); - } #endif + } SYNCHRONOUSLY_BLOCKED_END();
- NtReleaseKeyedEvent(keyed_event, this->unk_active.next, 0, NULL); + if (!skip_release) + NtReleaseKeyedEvent(keyed_event, this->unk_active.next, 0, NULL); }
/* ?native_handle@critical_section@Concurrency@@QAEAAV12@XZ */ @@ -2475,6 +2518,7 @@ bool __thiscall critical_section_try_lock_for( critical_section *this, unsigned int timeout) { cs_queue *q, *last; + BOOL timed_out = FALSE;
TRACE("(%p %d)\n", this, timeout);
@@ -2487,32 +2531,39 @@ bool __thiscall critical_section_try_lock_for( if(!(q = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*q)))) return critical_section_try_lock(this);
- last = InterlockedExchangePointer(&this->tail, q); - if(last) { - LARGE_INTEGER to; - NTSTATUS status; - FILETIME ft; - - last->next = q; - GetSystemTimeAsFileTime(&ft); - to.QuadPart = ((LONGLONG)ft.dwHighDateTime << 32) + - ft.dwLowDateTime + (LONGLONG)timeout * TICKSPERMSEC; - status = NtWaitForKeyedEvent(keyed_event, q, 0, &to); - if(status == STATUS_TIMEOUT) { - if(!InterlockedExchange(&q->free, TRUE)) - return FALSE; - /* A thread has signaled the event and is block waiting. */ - /* We need to catch the event to wake the thread. */ - NtWaitForKeyedEvent(keyed_event, q, 0, NULL); + SYNCHRONOUSLY_BLOCKED_START(get_current_context()) { + last = InterlockedExchangePointer(&this->tail, q); + if(last) { + LARGE_INTEGER to; + NTSTATUS status; + FILETIME ft; + + last->next = q; + GetSystemTimeAsFileTime(&ft); + to.QuadPart = ((LONGLONG)ft.dwHighDateTime << 32) + + ft.dwLowDateTime + (LONGLONG)timeout * TICKSPERMSEC; + status = NtWaitForKeyedEvent(keyed_event, q, 0, &to); + if(status == STATUS_TIMEOUT) { + if(!InterlockedExchange(&q->free, TRUE)) { + timed_out = TRUE; + goto end; + } + /* A thread has signaled the event and is block waiting. */ + /* We need to catch the event to wake the thread. */ + NtWaitForKeyedEvent(keyed_event, q, 0, NULL); + } } - }
- cs_set_head(this, q); - if(InterlockedCompareExchangePointer(&this->tail, &this->unk_active, q) != q) { - spin_wait_for_next_cs(q); - this->unk_active.next = q->next; - } + cs_set_head(this, q); + if(InterlockedCompareExchangePointer(&this->tail, &this->unk_active, q) != q) { + spin_wait_for_next_cs(q); + this->unk_active.next = q->next; + } + end:; + } SYNCHRONOUSLY_BLOCKED_END();
+ if (timed_out) + return FALSE; HeapFree(GetProcessHeap(), 0, q); return TRUE; } @@ -2749,10 +2800,11 @@ static size_t evt_wait(thread_wait *wait, event **events, int count, bool wait_a if(!evt_transition(&wait->signaled, EVT_RUNNING, EVT_WAITING)) return evt_end_wait(wait, events, count);
- status = NtWaitForKeyedEvent(keyed_event, wait, 0, evt_timeout(&ntto, timeout)); - - if(status && !evt_transition(&wait->signaled, EVT_WAITING, EVT_RUNNING)) - NtWaitForKeyedEvent(keyed_event, wait, 0, NULL); + SYNCHRONOUSLY_BLOCKED_START(get_current_context()) { + status = NtWaitForKeyedEvent(keyed_event, wait, 0, evt_timeout(&ntto, timeout)); + if(status && !evt_transition(&wait->signaled, EVT_WAITING, EVT_RUNNING)) + NtWaitForKeyedEvent(keyed_event, wait, 0, NULL); + } SYNCHRONOUSLY_BLOCKED_END();
return evt_end_wait(wait, events, count); } @@ -2939,8 +2991,10 @@ void __thiscall _Condition_variable_wait(_Condition_variable *this, critical_sec critical_section_unlock(&this->lock);
critical_section_unlock(cs); - while (q.next != CV_WAKE) - RtlWaitOnAddress(&q.next, &next, sizeof(next), NULL); + SYNCHRONOUSLY_BLOCKED_START(get_current_context()) { + while (q.next != CV_WAKE) + RtlWaitOnAddress(&q.next, &next, sizeof(next), NULL); + } SYNCHRONOUSLY_BLOCKED_END(); critical_section_lock(cs); }
@@ -2954,6 +3008,7 @@ bool __thiscall _Condition_variable_wait_for(_Condition_variable *this, NTSTATUS status; FILETIME ft; cv_queue *q, *next; + BOOL result = TRUE;
TRACE("(%p %p %d)\n", this, cs, timeout);
@@ -2967,23 +3022,24 @@ bool __thiscall _Condition_variable_wait_for(_Condition_variable *this,
critical_section_unlock(cs);
- GetSystemTimeAsFileTime(&ft); - to.QuadPart = ((LONGLONG)ft.dwHighDateTime << 32) + - ft.dwLowDateTime + (LONGLONG)timeout * TICKSPERMSEC; - while (q->next != CV_WAKE) { - status = RtlWaitOnAddress(&q->next, &next, sizeof(next), &to); - if(status == STATUS_TIMEOUT) { - if(!InterlockedExchange(&q->expired, TRUE)) { - critical_section_lock(cs); - return FALSE; + SYNCHRONOUSLY_BLOCKED_START(get_current_context()) { + GetSystemTimeAsFileTime(&ft); + to.QuadPart = ((LONGLONG)ft.dwHighDateTime << 32) + + ft.dwLowDateTime + (LONGLONG)timeout * TICKSPERMSEC; + while (q->next != CV_WAKE) { + status = RtlWaitOnAddress(&q->next, &next, sizeof(next), &to); + if(status == STATUS_TIMEOUT) { + if(!InterlockedExchange(&q->expired, TRUE)) + result = FALSE; + break; } - break; } - } + } SYNCHRONOUSLY_BLOCKED_END();
- operator_delete(q); + if (result) + operator_delete(q); critical_section_lock(cs); - return TRUE; + return result; }
/* ?notify_one@_Condition_variable@details@Concurrency@@QAEXXZ */ @@ -3109,18 +3165,25 @@ void __thiscall reader_writer_lock_lock(reader_writer_lock *this) last = InterlockedExchangePointer((void**)&this->writer_tail, &q); if (last) { last->next = &q; - NtWaitForKeyedEvent(keyed_event, &q, 0, NULL); + SYNCHRONOUSLY_BLOCKED_START(get_current_context()) { + NtWaitForKeyedEvent(keyed_event, &q, 0, NULL); + } SYNCHRONOUSLY_BLOCKED_END(); } else { this->writer_head = &q; - if (InterlockedOr(&this->count, WRITER_WAITING)) - NtWaitForKeyedEvent(keyed_event, &q, 0, NULL); + if (InterlockedOr(&this->count, WRITER_WAITING)) { + SYNCHRONOUSLY_BLOCKED_START(get_current_context()) { + NtWaitForKeyedEvent(keyed_event, &q, 0, NULL); + } SYNCHRONOUSLY_BLOCKED_END(); + } }
this->thread_id = GetCurrentThreadId(); this->writer_head = &this->active; this->active.next = NULL; if (InterlockedCompareExchangePointer((void**)&this->writer_tail, &this->active, &q) != &q) { - spin_wait_for_next_rwl(&q); + SYNCHRONOUSLY_BLOCKED_START(get_current_context()) { + spin_wait_for_next_rwl(&q); + } SYNCHRONOUSLY_BLOCKED_END(); this->active.next = q.next; } } @@ -3151,8 +3214,10 @@ void __thiscall reader_writer_lock_lock_read(reader_writer_lock *this) while (!((count = this->count) & WRITER_WAITING)) if (InterlockedCompareExchange(&this->count, count+1, count) == count) break;
- if (count & WRITER_WAITING) - NtWaitForKeyedEvent(keyed_event, &q, 0, NULL); + SYNCHRONOUSLY_BLOCKED_START(get_current_context()) { + if (count & WRITER_WAITING) + NtWaitForKeyedEvent(keyed_event, &q, 0, NULL); + } SYNCHRONOUSLY_BLOCKED_END();
head = InterlockedExchangePointer((void**)&this->reader_head, NULL); while(head && head != &q) { @@ -3162,7 +3227,9 @@ void __thiscall reader_writer_lock_lock_read(reader_writer_lock *this) head = next; } } else { - NtWaitForKeyedEvent(keyed_event, &q, 0, NULL); + SYNCHRONOUSLY_BLOCKED_START(get_current_context()) { + NtWaitForKeyedEvent(keyed_event, &q, 0, NULL); + } SYNCHRONOUSLY_BLOCKED_END(); } }
@@ -3186,7 +3253,9 @@ bool __thiscall reader_writer_lock_try_lock(reader_writer_lock *this) this->writer_head = &this->active; this->active.next = NULL; if (InterlockedCompareExchangePointer((void**)&this->writer_tail, &this->active, &q) != &q) { - spin_wait_for_next_rwl(&q); + SYNCHRONOUSLY_BLOCKED_START(get_current_context()) { + spin_wait_for_next_rwl(&q); + } SYNCHRONOUSLY_BLOCKED_END(); this->active.next = q.next; } return TRUE; @@ -3194,7 +3263,9 @@ bool __thiscall reader_writer_lock_try_lock(reader_writer_lock *this)
if (InterlockedCompareExchangePointer((void**)&this->writer_tail, NULL, &q) == &q) return FALSE; - spin_wait_for_next_rwl(&q); + SYNCHRONOUSLY_BLOCKED_START(get_current_context()) { + spin_wait_for_next_rwl(&q); + } SYNCHRONOUSLY_BLOCKED_END(); this->writer_head = q.next; if (!InterlockedOr(&this->count, WRITER_WAITING)) { this->thread_id = GetCurrentThreadId(); @@ -3330,7 +3401,9 @@ DEFINE_THISCALL_WRAPPER(_ReentrantBlockingLock__Acquire, 4) void __thiscall _ReentrantBlockingLock__Acquire(_ReentrantBlockingLock *this) { TRACE("(%p)\n", this); - EnterCriticalSection(&this->cs); + SYNCHRONOUSLY_BLOCKED_START(get_current_context()) { + EnterCriticalSection(&this->cs); + } SYNCHRONOUSLY_BLOCKED_END(); }
/* ?_Release@_ReentrantBlockingLock@details@Concurrency@@QAEXXZ */ @@ -3358,7 +3431,9 @@ void __cdecl Concurrency_wait(unsigned int time)
if (!once++) FIXME("(%d) stub!\n", time);
- Sleep(time); + SYNCHRONOUSLY_BLOCKED_START(get_current_context()) { + Sleep(time); + } SYNCHRONOUSLY_BLOCKED_END(); }
#if _MSVCR_VER>=110
On Tue Mar 28 17:33:54 2023 +0000, Torge Matthies wrote:
The class is some kind of implementation detail of the public `cancellation_token` class, which can be used to cancel asynchronous operations. I tried to find out what it's supposed to point to but couldn't figure it out. A pointer to a `NULL` pointer seems to work for this game.
@piotr I could set the `unknown` pointer to `HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(void*))` instead if you'd like that better.
On Wed Apr 12 13:50:29 2023 +0000, **** wrote:
Marvin replied on the mailing list:
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=131820 Your paranoid android. === debian11 (build log) === ../wine/dlls/msvcrt/concurrency.c:2562:5: error: label at end of compound statement ../wine/dlls/msvcrt/concurrency.c:2562:5: error: label at end of compound statement ../wine/dlls/msvcrt/concurrency.c:2562:5: error: label at end of compound statement Task: The win32 Wine build failed === debian11b (build log) === ../wine/dlls/msvcrt/concurrency.c:2562:5: error: label at end of compound statement ../wine/dlls/msvcrt/concurrency.c:2562:5: error: label at end of compound statement ../wine/dlls/msvcrt/concurrency.c:2562:5: error: label at end of compound statement Task: The wow64 Wine build failed
old compiler or strict warnings