asar coverage - build #272


src/asar/
File: src/asar/platform/windows/thread-helpers-win32.h
Date: 2025-03-03 19:47:10
Lines:
23/24
95.8%
Functions:
7/10
70.0%
Branches:
10/18
55.6%

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