[KERNEL32_WINETEST]
[reactos.git] / rostests / winetests / kernel32 / fiber.c
1 /*
2 * Unit tests for fiber functions
3 *
4 * Copyright (c) 2010 André Hentschel
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #include "wine/test.h"
22
23 static LPVOID (WINAPI *pCreateFiber)(SIZE_T,LPFIBER_START_ROUTINE,LPVOID);
24 static LPVOID (WINAPI *pConvertThreadToFiber)(LPVOID);
25 static BOOL (WINAPI *pConvertFiberToThread)(void);
26 static void (WINAPI *pSwitchToFiber)(LPVOID);
27 static void (WINAPI *pDeleteFiber)(LPVOID);
28 static LPVOID (WINAPI *pConvertThreadToFiberEx)(LPVOID,DWORD);
29 static LPVOID (WINAPI *pCreateFiberEx)(SIZE_T,SIZE_T,DWORD,LPFIBER_START_ROUTINE,LPVOID);
30 static BOOL (WINAPI *pIsThreadAFiber)(void);
31 static DWORD (WINAPI *pFlsAlloc)(PFLS_CALLBACK_FUNCTION);
32 static BOOL (WINAPI *pFlsFree)(DWORD);
33 static PVOID (WINAPI *pFlsGetValue)(DWORD);
34 static BOOL (WINAPI *pFlsSetValue)(DWORD,PVOID);
35
36 static LPVOID fibers[2];
37 static BYTE testparam = 185;
38 static WORD cbCount;
39
40 static VOID init_funcs(void)
41 {
42 HMODULE hKernel32 = GetModuleHandle("kernel32");
43
44 #define X(f) p##f = (void*)GetProcAddress(hKernel32, #f);
45 X(CreateFiber);
46 X(ConvertThreadToFiber);
47 X(ConvertFiberToThread);
48 X(SwitchToFiber);
49 X(DeleteFiber);
50 X(ConvertThreadToFiberEx);
51 X(CreateFiberEx);
52 X(IsThreadAFiber);
53 X(FlsAlloc);
54 X(FlsFree);
55 X(FlsGetValue);
56 X(FlsSetValue);
57 #undef X
58 }
59
60 static VOID WINAPI FiberLocalStorageProc(PVOID lpFlsData)
61 {
62 cbCount++;
63 ok(lpFlsData == (PVOID) 1587, "FlsData expected not to be changed\n");
64 }
65
66 static VOID WINAPI FiberMainProc(LPVOID lpFiberParameter)
67 {
68 BYTE *tparam = (BYTE *)lpFiberParameter;
69 cbCount++;
70 ok(*tparam == 185, "Parameterdata expected not to be changed\n");
71 pSwitchToFiber(fibers[0]);
72 }
73
74 static void test_ConvertThreadToFiber(void)
75 {
76 if (pConvertThreadToFiber)
77 {
78 fibers[0] = pConvertThreadToFiber(&testparam);
79 ok(fibers[0] != 0, "ConvertThreadToFiber failed with error %d\n", GetLastError());
80 }
81 else
82 {
83 win_skip( "ConvertThreadToFiber not present\n" );
84 }
85 }
86
87 static void test_ConvertThreadToFiberEx(void)
88 {
89 if (pConvertThreadToFiberEx)
90 {
91 fibers[0] = pConvertThreadToFiberEx(&testparam, 0);
92 ok(fibers[0] != 0, "ConvertThreadToFiberEx failed with error %d\n", GetLastError());
93 }
94 else
95 {
96 win_skip( "ConvertThreadToFiberEx not present\n" );
97 }
98 }
99
100 static void test_ConvertFiberToThread(void)
101 {
102 if (pConvertFiberToThread)
103 {
104 ok(pConvertFiberToThread() , "ConvertFiberToThread failed with error %d\n", GetLastError());
105 }
106 else
107 {
108 win_skip( "ConvertFiberToThread not present\n" );
109 }
110 }
111
112 static void test_FiberHandling(void)
113 {
114 cbCount = 0;
115 fibers[0] = pCreateFiber(0,FiberMainProc,&testparam);
116 ok(fibers[0] != 0, "CreateFiber failed with error %d\n", GetLastError());
117 pDeleteFiber(fibers[0]);
118
119 test_ConvertThreadToFiber();
120 test_ConvertFiberToThread();
121 if (pConvertThreadToFiberEx)
122 test_ConvertThreadToFiberEx();
123 else
124 test_ConvertThreadToFiber();
125
126
127 fibers[1] = pCreateFiber(0,FiberMainProc,&testparam);
128 ok(fibers[1] != 0, "CreateFiber failed with error %d\n", GetLastError());
129
130 pSwitchToFiber(fibers[1]);
131 ok(cbCount == 1, "Wrong callback count: %d\n", cbCount);
132 pDeleteFiber(fibers[1]);
133
134 if (!pCreateFiberEx)
135 {
136 win_skip( "CreateFiberEx not present\n" );
137 return;
138 }
139
140 fibers[1] = pCreateFiberEx(0,0,0,FiberMainProc,&testparam);
141 ok(fibers[1] != 0, "CreateFiberEx failed with error %d\n", GetLastError());
142
143 pSwitchToFiber(fibers[1]);
144 ok(cbCount == 2, "Wrong callback count: %d\n", cbCount);
145 pDeleteFiber(fibers[1]);
146
147 if (!pIsThreadAFiber)
148 {
149 win_skip( "IsThreadAFiber not present\n" );
150 return;
151 }
152
153 ok(pIsThreadAFiber(), "IsThreadAFiber reported FALSE\n");
154 test_ConvertFiberToThread();
155 ok(!pIsThreadAFiber(), "IsThreadAFiber reported TRUE\n");
156 }
157
158 static void test_FiberLocalStorage(PFLS_CALLBACK_FUNCTION cbfunc)
159 {
160 DWORD fls;
161 BOOL ret;
162 PVOID val = (PVOID) 1587;
163
164 if (!pFlsAlloc)
165 {
166 win_skip( "Fiber Local Storage not supported\n" );
167 return;
168 }
169 cbCount = 0;
170
171 fls = pFlsAlloc(cbfunc);
172 ok(fls != FLS_OUT_OF_INDEXES, "FlsAlloc failed with error %d\n", GetLastError());
173
174 ret = pFlsSetValue(fls, val);
175 ok(ret, "FlsSetValue failed\n");
176 ok(val == pFlsGetValue(fls), "FlsGetValue failed\n");
177
178 ret = pFlsFree(fls);
179 ok(ret, "FlsFree failed\n");
180 if (cbfunc)
181 todo_wine ok(cbCount == 1, "Wrong callback count: %d\n", cbCount);
182 }
183
184 START_TEST(fiber)
185 {
186 init_funcs();
187
188 if (!pCreateFiber)
189 {
190 win_skip( "Fibers not supported by win95\n" );
191 return;
192 }
193
194 test_FiberHandling();
195 test_FiberLocalStorage(NULL);
196 test_FiberLocalStorage(FiberLocalStorageProc);
197 }