Commit 4c54f9ae authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

msvcp140: Add {_Schedule,_Reschedule,_Release}_chore implementation.

parent 6288f0b4
......@@ -1581,8 +1581,8 @@
@ stub -arch=win32 ?_Raise_handler@std@@3P6AXABVexception@stdext@@@ZA
@ stub -arch=win64 ?_Raise_handler@std@@3P6AXAEBVexception@stdext@@@ZEA
@ cdecl ?_Random_device@std@@YAIXZ() _Random_device
@ stub -arch=win32 ?_Release_chore@details@Concurrency@@YAXPAU_Threadpool_chore@12@@Z
@ stub -arch=win64 ?_Release_chore@details@Concurrency@@YAXPEAU_Threadpool_chore@12@@Z
@ cdecl -arch=win32 ?_Release_chore@details@Concurrency@@YAXPAU_Threadpool_chore@12@@Z(ptr) _Release_chore
@ cdecl -arch=win64 ?_Release_chore@details@Concurrency@@YAXPEAU_Threadpool_chore@12@@Z(ptr) _Release_chore
@ cdecl -arch=win32 ?_Rep@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@DI@Z(ptr ptr long ptr long long) num_put_char__Rep
@ cdecl -arch=win64 ?_Rep@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@DU?$char_traits@D@std@@@2@V32@D_K@Z(ptr ptr ptr long long) num_put_char__Rep
@ cdecl -arch=win32 ?_Rep@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@GU?$char_traits@G@std@@@2@V32@GI@Z(ptr ptr long ptr long long) num_put_wchar__Rep
......@@ -1590,16 +1590,16 @@
@ cdecl -arch=win32 ?_Rep@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@_WI@Z(ptr ptr long ptr long long) num_put_wchar__Rep
@ cdecl -arch=win64 ?_Rep@?$num_put@_WV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBA?AV?$ostreambuf_iterator@_WU?$char_traits@_W@std@@@2@V32@_W_K@Z(ptr ptr ptr long long) num_put_wchar__Rep
@ stub ?_ReportUnobservedException@details@Concurrency@@YAXXZ
@ stub -arch=win32 ?_Reschedule_chore@details@Concurrency@@YAHPBU_Threadpool_chore@12@@Z
@ stub -arch=win64 ?_Reschedule_chore@details@Concurrency@@YAHPEBU_Threadpool_chore@12@@Z
@ cdecl -arch=win32 ?_Reschedule_chore@details@Concurrency@@YAHPBU_Threadpool_chore@12@@Z(ptr) _Reschedule_chore
@ cdecl -arch=win64 ?_Reschedule_chore@details@Concurrency@@YAHPEBU_Threadpool_chore@12@@Z(ptr) _Reschedule_chore
@ cdecl -arch=arm ?_Reset@_ContextCallback@details@Concurrency@@AAAXXZ(ptr) _ContextCallback__Reset
@ thiscall -arch=i386 ?_Reset@_ContextCallback@details@Concurrency@@AAEXXZ(ptr) _ContextCallback__Reset
@ cdecl -arch=win64 ?_Reset@_ContextCallback@details@Concurrency@@AEAAXXZ(ptr) _ContextCallback__Reset
@ stub ?_Rethrow_future_exception@std@@YAXVexception_ptr@1@@Z
@ stub -arch=win32 ?_Rng_abort@std@@YAXPBD@Z
@ stub -arch=win64 ?_Rng_abort@std@@YAXPEBD@Z
@ stub -arch=win32 ?_Schedule_chore@details@Concurrency@@YAHPAU_Threadpool_chore@12@@Z
@ stub -arch=win64 ?_Schedule_chore@details@Concurrency@@YAHPEAU_Threadpool_chore@12@@Z
@ cdecl -arch=win32 ?_Schedule_chore@details@Concurrency@@YAHPAU_Threadpool_chore@12@@Z(ptr) _Schedule_chore
@ cdecl -arch=win64 ?_Schedule_chore@details@Concurrency@@YAHPEAU_Threadpool_chore@12@@Z(ptr) _Schedule_chore
@ cdecl -arch=win32 ?_Setgloballocale@locale@std@@CAXPAX@Z(ptr) locale__Setgloballocale
@ cdecl -arch=win64 ?_Setgloballocale@locale@std@@CAXPEAX@Z(ptr) locale__Setgloballocale
@ stub -arch=win32 ?_Src@?1??_Getffld@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator@DU?$char_traits@D@std@@@3@1AAVios_base@3@PAH@Z@4QBDB
......
......@@ -125,6 +125,12 @@ typedef struct {
MSVCP_bool started;
} _TaskEventLogger;
typedef struct {
PTP_WORK work;
void (__cdecl *callback)(void*);
void *arg;
} _Threadpool_chore;
static unsigned int (__cdecl *p__Thrd_id)(void);
static task_continuation_context* (__thiscall *p_task_continuation_context_ctor)(task_continuation_context*);
static void (__thiscall *p__ContextCallback__Assign)(_ContextCallback*, void*);
......@@ -138,6 +144,9 @@ static void (__thiscall *p__TaskEventLogger__LogTaskCompleted)(_TaskEventLogger*
static void (__thiscall *p__TaskEventLogger__LogTaskExecutionCompleted)(_TaskEventLogger*);
static void (__thiscall *p__TaskEventLogger__LogWorkItemCompleted)(_TaskEventLogger*);
static void (__thiscall *p__TaskEventLogger__LogWorkItemStarted)(_TaskEventLogger*);
static int (__cdecl *p__Schedule_chore)(_Threadpool_chore*);
static int (__cdecl *p__Reschedule_chore)(const _Threadpool_chore*);
static void (__cdecl *p__Release_chore)(_Threadpool_chore*);
static HMODULE msvcp;
#define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y)
......@@ -166,6 +175,9 @@ static BOOL init(void)
SET(p__TaskEventLogger__LogTaskExecutionCompleted, "?_LogTaskExecutionCompleted@_TaskEventLogger@details@Concurrency@@QEAAXXZ");
SET(p__TaskEventLogger__LogWorkItemCompleted, "?_LogWorkItemCompleted@_TaskEventLogger@details@Concurrency@@QEAAXXZ");
SET(p__TaskEventLogger__LogWorkItemStarted, "?_LogWorkItemStarted@_TaskEventLogger@details@Concurrency@@QEAAXXZ");
SET(p__Schedule_chore, "?_Schedule_chore@details@Concurrency@@YAHPEAU_Threadpool_chore@12@@Z");
SET(p__Reschedule_chore, "?_Reschedule_chore@details@Concurrency@@YAHPEBU_Threadpool_chore@12@@Z");
SET(p__Release_chore, "?_Release_chore@details@Concurrency@@YAXPEAU_Threadpool_chore@12@@Z");
} else {
#ifdef __arm__
SET(p_task_continuation_context_ctor, "??0task_continuation_context@Concurrency@@AAA@XZ");
......@@ -192,6 +204,9 @@ static BOOL init(void)
SET(p__TaskEventLogger__LogWorkItemCompleted, "?_LogWorkItemCompleted@_TaskEventLogger@details@Concurrency@@QAEXXZ");
SET(p__TaskEventLogger__LogWorkItemStarted, "?_LogWorkItemStarted@_TaskEventLogger@details@Concurrency@@QAEXXZ");
#endif
SET(p__Schedule_chore, "?_Schedule_chore@details@Concurrency@@YAHPAU_Threadpool_chore@12@@Z");
SET(p__Reschedule_chore, "?_Reschedule_chore@details@Concurrency@@YAHPBU_Threadpool_chore@12@@Z");
SET(p__Release_chore, "?_Release_chore@details@Concurrency@@YAXPAU_Threadpool_chore@12@@Z");
}
init_thiscall_thunk();
......@@ -395,6 +410,57 @@ static void test__TaskEventLogger(void)
ok(logger.started, "logger.started = FALSE\n");
}
void __cdecl chore_callback(void *arg)
{
HANDLE event = arg;
SetEvent(event);
}
static void test_chore(void)
{
HANDLE event = CreateEventW(NULL, FALSE, FALSE, NULL);
_Threadpool_chore chore, old_chore;
DWORD wait;
int ret;
memset(&chore, 0, sizeof(chore));
ret = p__Schedule_chore(&chore);
ok(!ret, "_Schedule_chore returned %d\n", ret);
ok(chore.work != NULL, "chore.work == NULL\n");
ok(!chore.callback, "chore.callback != NULL\n");
p__Release_chore(&chore);
chore.work = NULL;
chore.callback = chore_callback;
chore.arg = event;
ret = p__Schedule_chore(&chore);
ok(!ret, "_Schedule_chore returned %d\n", ret);
ok(chore.work != NULL, "chore.work == NULL\n");
ok(chore.callback == chore_callback, "chore.callback = %p, expected %p\n", chore.callback, chore_callback);
ok(chore.arg == event, "chore.arg = %p, expected %p\n", chore.arg, event);
wait = WaitForSingleObject(event, 500);
ok(wait == WAIT_OBJECT_0, "WaitForSingleObject returned %d\n", wait);
old_chore = chore;
ret = p__Schedule_chore(&chore);
ok(!ret, "_Schedule_chore returned %d\n", ret);
ok(old_chore.work != chore.work, "new threadpool work was not created\n");
p__Release_chore(&old_chore);
wait = WaitForSingleObject(event, 500);
ok(wait == WAIT_OBJECT_0, "WaitForSingleObject returned %d\n", wait);
ret = p__Reschedule_chore(&chore);
ok(!ret, "_Reschedule_chore returned %d\n", ret);
wait = WaitForSingleObject(event, 500);
ok(wait == WAIT_OBJECT_0, "WaitForSingleObject returned %d\n", wait);
p__Release_chore(&chore);
ok(!chore.work, "chore.work != NULL\n");
ok(chore.callback == chore_callback, "chore.callback = %p, expected %p\n", chore.callback, chore_callback);
ok(chore.arg == event, "chore.arg = %p, expected %p\n", chore.arg, event);
p__Release_chore(&chore);
}
START_TEST(msvcp140)
{
if(!init()) return;
......@@ -403,5 +469,6 @@ START_TEST(msvcp140)
test_task_continuation_context();
test__ContextCallback();
test__TaskEventLogger();
test_chore();
FreeLibrary(msvcp);
}
......@@ -1520,4 +1520,53 @@ void __thiscall _TaskEventLogger__LogWorkItemStarted(_TaskEventLogger *this)
{
TRACE("(%p)\n", this);
}
typedef struct {
PTP_WORK work;
void (__cdecl *callback)(void*);
void *arg;
} _Threadpool_chore;
/* ?_Reschedule_chore@details@Concurrency@@YAHPBU_Threadpool_chore@12@@Z */
/* ?_Reschedule_chore@details@Concurrency@@YAHPEBU_Threadpool_chore@12@@Z */
int __cdecl _Reschedule_chore(const _Threadpool_chore *chore)
{
TRACE("(%p)\n", chore);
SubmitThreadpoolWork(chore->work);
return 0;
}
static void WINAPI threadpool_callback(PTP_CALLBACK_INSTANCE instance, void *context, PTP_WORK work)
{
_Threadpool_chore *chore = context;
TRACE("calling chore callback: %p\n", chore);
if (chore->callback)
chore->callback(chore->arg);
}
/* ?_Schedule_chore@details@Concurrency@@YAHPAU_Threadpool_chore@12@@Z */
/* ?_Schedule_chore@details@Concurrency@@YAHPEAU_Threadpool_chore@12@@Z */
int __cdecl _Schedule_chore(_Threadpool_chore *chore)
{
TRACE("(%p)\n", chore);
chore->work = CreateThreadpoolWork(threadpool_callback, chore, NULL);
/* FIXME: what should be returned in case of error */
if(!chore->work)
return -1;
return _Reschedule_chore(chore);
}
/* ?_Release_chore@details@Concurrency@@YAXPAU_Threadpool_chore@12@@Z */
/* ?_Release_chore@details@Concurrency@@YAXPEAU_Threadpool_chore@12@@Z */
void __cdecl _Release_chore(_Threadpool_chore *chore)
{
TRACE("(%p)\n", chore);
if(!chore->work) return;
CloseThreadpoolWork(chore->work);
chore->work = NULL;
}
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment