Piotr Caban : msvcrt: Add ThreadScheduler::Attach implementation.

Alexandre Julliard julliard at winehq.org
Fri Mar 31 14:26:27 CDT 2017


Module: wine
Branch: master
Commit: dbb4e8553ffcea1ee8e679304b17bf96b6451382
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=dbb4e8553ffcea1ee8e679304b17bf96b6451382

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Thu Mar 30 22:47:23 2017 +0200

msvcrt: Add ThreadScheduler::Attach implementation.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msvcrt/scheduler.c | 42 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 39 insertions(+), 3 deletions(-)

diff --git a/dlls/msvcrt/scheduler.c b/dlls/msvcrt/scheduler.c
index 3247b63..f0fda9f 100644
--- a/dlls/msvcrt/scheduler.c
+++ b/dlls/msvcrt/scheduler.c
@@ -96,17 +96,24 @@ union allocator_cache_entry {
     } alloc;
 };
 
+struct scheduler_list {
+    struct Scheduler *scheduler;
+    struct scheduler_list *next;
+};
+
 typedef struct {
     Context context;
+    struct scheduler_list scheduler;
     unsigned int id;
     union allocator_cache_entry *allocator_cache[8];
 } ExternalContextBase;
 extern const vtable_ptr MSVCRT_ExternalContextBase_vtable;
 static void ExternalContextBase_ctor(ExternalContextBase*);
 
-typedef struct {
+typedef struct Scheduler {
     const vtable_ptr *vtable;
 } Scheduler;
+#define call_Scheduler_Release(this) CALL_VTBL_FUNC(this, 20, unsigned int, (Scheduler*), (this))
 
 typedef struct {
     Scheduler scheduler;
@@ -255,6 +262,7 @@ MSVCRT_bool __thiscall ExternalContextBase_IsSynchronouslyBlocked(const External
 
 static void ExternalContextBase_dtor(ExternalContextBase *this)
 {
+    struct scheduler_list *scheduler_cur, *scheduler_next;
     union allocator_cache_entry *next, *cur;
     int i;
 
@@ -265,6 +273,16 @@ static void ExternalContextBase_dtor(ExternalContextBase *this)
             MSVCRT_operator_delete(cur);
         }
     }
+
+    if (this->scheduler.scheduler) {
+        call_Scheduler_Release(this->scheduler.scheduler);
+
+        for(scheduler_cur=this->scheduler.next; scheduler_cur; scheduler_cur=scheduler_next) {
+            scheduler_next = scheduler_cur->next;
+            call_Scheduler_Release(scheduler_cur->scheduler);
+            MSVCRT_operator_delete(scheduler_cur);
+        }
+    }
 }
 
 DEFINE_THISCALL_WRAPPER(ExternalContextBase_vector_dtor, 8)
@@ -291,9 +309,9 @@ static void ExternalContextBase_ctor(ExternalContextBase *this)
 {
     TRACE("(%p)->()\n", this);
 
+    memset(this, 0, sizeof(*this));
     this->context.vtable = &MSVCRT_ExternalContextBase_vtable;
     this->id = InterlockedIncrement(&context_id);
-    memset(this->allocator_cache, 0, sizeof(this->allocator_cache));
 }
 
 /* ?Alloc at Concurrency@@YAPAXI at Z */
@@ -607,7 +625,25 @@ void __thiscall ThreadScheduler_RegisterShutdownEvent(ThreadScheduler *this, HAN
 DEFINE_THISCALL_WRAPPER(ThreadScheduler_Attach, 4)
 void __thiscall ThreadScheduler_Attach(ThreadScheduler *this)
 {
-    FIXME("(%p) stub\n", this);
+    ExternalContextBase *context = (ExternalContextBase*)get_current_context();
+
+    TRACE("(%p)\n", this);
+
+    if(context->context.vtable != &MSVCRT_ExternalContextBase_vtable) {
+        ERR("unknown context set\n");
+        return;
+    }
+
+    if(context->scheduler.scheduler == &this->scheduler)
+        throw_exception(EXCEPTION_IMPROPER_SCHEDULER_ATTACH, 0, NULL);
+
+    if(context->scheduler.scheduler) {
+        struct scheduler_list *l = MSVCRT_operator_new(sizeof(*l));
+        *l = context->scheduler;
+        context->scheduler.next = l;
+    }
+    context->scheduler.scheduler = &this->scheduler;
+    ThreadScheduler_Reference(this);
 }
 
 DEFINE_THISCALL_WRAPPER(ThreadScheduler_CreateScheduleGroup_loc, 8)




More information about the wine-cvs mailing list