asar coverage - build #208


src/asar/
File: src/asar/platform/windows/thread-helpers-win32.h
Date: 2024-02-19 22:06:19
Lines:
27/30
90.0%
Functions:
8/8
100.0%
Branches:
6/12
50.0%

Line Branch Exec Source
1 #pragma once
2
3 #if defined(_WIN32)
4
5 #include <windows.h>
6
7 struct function_pointer_wrapper /*have this struct at global level*/
8 {
9 static void (*fiber_callback)(void *);
10 369 static void __stdcall execute_fiber(void* parameter) { return fiber_callback(parameter); }
11
12 static unsigned long (*thread_callback)(void*);
13 static unsigned long __stdcall execute_thread(void* parameter) { return thread_callback(parameter); }
14 };
15
16 void (*function_pointer_wrapper::fiber_callback)(void*) = nullptr;
17 unsigned long (*function_pointer_wrapper::thread_callback)(void*) = nullptr;
18
19 template <typename functor>
20 369 bool run_as_fiber(functor &&callback) {
21 struct fiber_wrapper {
22 functor &callback;
23 void *original;
24 bool result;
25
26 369 void execute() {
27 369 result = callback();
28 369 SwitchToFiber(original);
29 }
30
31 369 } wrapper{callback, nullptr, false};
32
33 369 function_pointer_wrapper::fiber_callback = [](void *parameter){
34 reinterpret_cast<fiber_wrapper*>(parameter)->execute();
35 };
36 369 auto fiber = CreateFiberEx(16*1024*1024, 16*1024*1024, 0, &function_pointer_wrapper::execute_fiber, &wrapper);
37
38
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 369 times.
369 if (!fiber) {
39 return callback();
40 }
41
42 369 void* main_thread = ConvertThreadToFiber(nullptr);
43
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 369 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
369 if (!main_thread && GetLastError() != ERROR_ALREADY_FIBER) {
44 return callback();
45 }
46 369 wrapper.original = GetCurrentFiber();
47 369 SwitchToFiber(fiber);
48 369 DeleteFiber(fiber);
49
1/2
✓ Branch 0 taken 369 times.
✗ Branch 1 not taken.
369 if (main_thread) {
50 369 ConvertFiberToThread();
51 }
52 369 return wrapper.result;
53 }
54
55
56 template <typename functor>
57 bool run_as_thread(functor&& callback) {
58 struct thread_wrapper {
59 functor& callback;
60 bool result;
61
62 unsigned long execute() {
63 result = callback();
64 return (result ? 0 : -1);
65 }
66
67 } wrapper{ callback, false };
68
69 function_pointer_wrapper::thread_callback = [](void* parameter) {
70 return reinterpret_cast<thread_wrapper*>(parameter)->execute();
71 };
72
73 auto thread = CreateThread(NULL, 16 * 1024 * 1024, &function_pointer_wrapper::execute_thread, &wrapper, 0, NULL);
74
75 if (!thread) {
76 return callback();
77 }
78
79 WaitForSingleObject(thread, INFINITE);
80
81 CloseHandle(thread);
82
83 return wrapper.result;
84 }
85
86 char* stack_bottom = nullptr;
87 1077 void init_stack_use_check() {
88 MEMORY_BASIC_INFORMATION mbi;
89 1077 char stackvar = 0;
90 1077 VirtualQuery(&stackvar, &mbi, sizeof(mbi));
91 1077 stack_bottom = (char*)mbi.AllocationBase;
92 1077 }
93 1062 void deinit_stack_use_check() {
94 1062 stack_bottom = nullptr;
95 1062 }
96 205613 bool have_enough_stack_left() {
97 char stackvar;
98
3/4
✓ Branch 0 taken 205431 times.
✓ Branch 1 taken 182 times.
✓ Branch 2 taken 205431 times.
✗ Branch 3 not taken.
205613 return stack_bottom == nullptr || (&stackvar - stack_bottom) >= 32768;
99 }
100 #endif
101