kernel32/tests: Fix a test for real hardware.
[wine] / dlls / kernel32 / tests / 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         BOOL ret = pConvertFiberToThread();
105         ok(ret, "ConvertFiberToThread failed with error %d\n", GetLastError());
106     }
107     else
108     {
109         win_skip( "ConvertFiberToThread not present\n" );
110     }
111 }
112
113 static void test_FiberHandling(void)
114 {
115     cbCount = 0;
116     fibers[0] = pCreateFiber(0,FiberMainProc,&testparam);
117     ok(fibers[0] != 0, "CreateFiber failed with error %d\n", GetLastError());
118     pDeleteFiber(fibers[0]);
119
120     test_ConvertThreadToFiber();
121     test_ConvertFiberToThread();
122     if (pConvertThreadToFiberEx)
123         test_ConvertThreadToFiberEx();
124     else
125         test_ConvertThreadToFiber();
126
127
128     fibers[1] = pCreateFiber(0,FiberMainProc,&testparam);
129     ok(fibers[1] != 0, "CreateFiber failed with error %d\n", GetLastError());
130
131     pSwitchToFiber(fibers[1]);
132     ok(cbCount == 1, "Wrong callback count: %d\n", cbCount);
133     pDeleteFiber(fibers[1]);
134
135     if (!pCreateFiberEx)
136     {
137         win_skip( "CreateFiberEx not present\n" );
138         return;
139     }
140
141     SetLastError(0xdeadbeef);
142     fibers[1] = pCreateFiberEx(0,0,0,FiberMainProc,&testparam);
143     ok(fibers[1] != 0, "CreateFiberEx failed with error %d\n", GetLastError());
144
145     pSwitchToFiber(fibers[1]);
146     ok(cbCount == 2, "Wrong callback count: %d\n", cbCount);
147     pDeleteFiber(fibers[1]);
148
149     if (!pIsThreadAFiber)
150     {
151         win_skip( "IsThreadAFiber not present\n" );
152         return;
153     }
154
155     ok(pIsThreadAFiber(), "IsThreadAFiber reported FALSE\n");
156     test_ConvertFiberToThread();
157     ok(!pIsThreadAFiber(), "IsThreadAFiber reported TRUE\n");
158 }
159
160 static void test_FiberLocalStorage(PFLS_CALLBACK_FUNCTION cbfunc)
161 {
162     DWORD fls;
163     BOOL ret;
164     PVOID val = (PVOID) 1587;
165
166     if (!pFlsAlloc)
167     {
168         win_skip( "Fiber Local Storage not supported\n" );
169         return;
170     }
171     cbCount = 0;
172
173     fls = pFlsAlloc(cbfunc);
174     ok(fls != FLS_OUT_OF_INDEXES, "FlsAlloc failed with error %d\n", GetLastError());
175
176     ret = pFlsSetValue(fls, val);
177     ok(ret, "FlsSetValue failed\n");
178     ok(val == pFlsGetValue(fls), "FlsGetValue failed\n");
179
180     ret = pFlsFree(fls);
181     ok(ret, "FlsFree failed\n");
182     if (cbfunc)
183         todo_wine ok(cbCount == 1, "Wrong callback count: %d\n", cbCount);
184 }
185
186 START_TEST(fiber)
187 {
188     init_funcs();
189
190     if (!pCreateFiber)
191     {
192         win_skip( "Fibers not supported by win95\n" );
193         return;
194     }
195
196     test_FiberHandling();
197     test_FiberLocalStorage(NULL);
198     test_FiberLocalStorage(FiberLocalStorageProc);
199 }