1 |
// $Header$ |
//$Header$ |
2 |
//------------------------------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
3 |
//This file is part of "kicker", a program for spawning threads and/or processes periodically in |
//This file is part of "kicker", a program for spawning threads periodically in order to |
4 |
//order to unstall certain Windows programs and scripts. The cause of the stall is unknown, but |
//unstall certain Windows programs and scripts. The cause of the stall is unknown, but |
5 |
//it is known that spawning threads and/or processes unstalls the system. |
//it is known that spawning threads unstalls the system. |
6 |
//------------------------------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
7 |
//This source code and any program in which it is compiled/used is provided under the MIT License, |
//This source code and any program in which it is compiled/used is provided under the MIT License, |
8 |
//reproduced below. |
//reproduced below. |
25 |
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
26 |
//SOFTWARE. |
//SOFTWARE. |
27 |
//------------------------------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
|
#include <assert.h> |
|
|
#include <malloc.h> |
|
28 |
#include <process.h> |
#include <process.h> |
29 |
#include <stdio.h> |
#include <stdio.h> |
30 |
#include <string.h> |
#include <string.h> |
31 |
#include <time.h> |
#include <windows.h> |
32 |
|
|
33 |
|
#define NELEM(A) (sizeof(A)/sizeof(A[0])) |
34 |
|
|
35 |
|
void emit_hline_std(void) |
36 |
|
{ |
37 |
|
printf("-------------------------------------------------------------------------------\n"); |
38 |
|
} |
39 |
|
|
40 |
|
void emit_mit_license(void) |
41 |
|
{ |
42 |
|
const char *ref[] = |
43 |
|
{ |
44 |
|
"Permission is hereby granted, free of charge, to any person obtaining a copy", |
45 |
|
"of this software and associated documentation files(the \"Software\"), to", |
46 |
|
"deal in the Software without restriction, including without limitation the", |
47 |
|
"rights to use, copy, modify, merge, publish, distribute, sublicense, and / or", |
48 |
|
"sell copies of the Software, and to permit persons to whom the Software is", |
49 |
|
"furnished to do so, subject to the following conditions :", |
50 |
|
"", |
51 |
|
"The above copyright notice and this permission notice shall be included in", |
52 |
|
"all copies or substantial portions of the Software.", |
53 |
|
"", |
54 |
|
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR", |
55 |
|
"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", |
56 |
|
"FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE", |
57 |
|
"AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", |
58 |
|
"LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,", |
59 |
|
"OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE", |
60 |
|
"SOFTWARE." |
61 |
|
}; |
62 |
|
|
63 |
|
size_t i; |
64 |
|
|
65 |
|
for (i=0; i<NELEM(ref); i++) |
66 |
|
{ |
67 |
|
printf("%s\n", ref[i]); |
68 |
|
} |
69 |
|
} |
70 |
|
|
71 |
|
const char *kickish_words[] = |
72 |
|
{ |
73 |
|
"Kick", |
74 |
|
"Smack", |
75 |
|
"Slug", |
76 |
|
"Punch", |
77 |
|
"Assault", |
78 |
|
"Hit", |
79 |
|
"Strike", |
80 |
|
"Slap", |
81 |
|
"Smack", |
82 |
|
"Spank", |
83 |
|
"Cuff", |
84 |
|
"Thump", |
85 |
|
"Swat", |
86 |
|
"Beat", |
87 |
|
"Thrash", |
88 |
|
"Batter", |
89 |
|
"Pound", |
90 |
|
"Pummel", |
91 |
|
"Box", |
92 |
|
"Whip", |
93 |
|
"Flog", |
94 |
|
"Cane", |
95 |
|
"Wallop", |
96 |
|
"Bash", |
97 |
|
"Bop", |
98 |
|
"Clout", |
99 |
|
"Clip", |
100 |
|
"Clobber", |
101 |
|
"Sock", |
102 |
|
"Swipe", |
103 |
|
"Crown", |
104 |
|
"Belt", |
105 |
|
"Tan", |
106 |
|
"Deck", |
107 |
|
"Floor", |
108 |
|
"Bump", |
109 |
|
"Knock", |
110 |
|
"Bang", |
111 |
|
"Tap", |
112 |
|
"Welt" |
113 |
|
}; |
114 |
|
|
115 |
|
volatile int ctrl_c_or_break_pressed = 0; //volatile because the Visual C++ environment spawns a thread to handle |
116 |
|
//CTRL-C or CTRL-BREAK. |
117 |
|
volatile int thread_ran = 0; //volatile because shared with thread. |
118 |
|
|
119 |
|
BOOL CtrlHandler(DWORD fdwCtrlType) |
120 |
|
{ |
121 |
|
switch (fdwCtrlType) |
122 |
|
{ |
123 |
|
case CTRL_C_EVENT: |
124 |
|
case CTRL_BREAK_EVENT: |
125 |
|
ctrl_c_or_break_pressed = 1; |
126 |
|
return(TRUE); |
127 |
|
//There is no default case. There is no break statement. I've assigned a |
128 |
|
//magic number to a variable. But the function still works fine. |
129 |
|
//Can you believe it? It must be a miracle! |
130 |
|
} |
131 |
|
|
132 |
|
return(FALSE); //Did I mention the multiple return points? This program should |
133 |
|
//blow up and wipe out several city blocks! |
134 |
|
} |
135 |
|
|
136 |
|
//Thread function. Parameter ignored. |
137 |
|
DWORD WINAPI MyThreadFunction(LPVOID lpParam) |
138 |
|
{ |
139 |
|
thread_ran = 1; |
140 |
|
|
141 |
|
return (0); |
142 |
|
} |
143 |
|
|
144 |
int c_main(int argc, char* argv[]) |
int c_main(int argc, char* argv[]) |
145 |
|
{ |
146 |
|
size_t selector = NELEM(kickish_words) - 1; |
147 |
|
size_t ui; |
148 |
|
int first_time = 1; |
149 |
|
HANDLE thread_handle; |
150 |
|
DWORD thread_id; |
151 |
|
|
152 |
|
emit_hline_std(); |
153 |
|
printf("kicker, Copyright 2016 David T. Ashley (dashley@gmail.com)\n"); |
154 |
|
emit_hline_std(); |
155 |
|
printf("This program is made available under the MIT License, reproduced below.\n"); |
156 |
|
emit_hline_std(); |
157 |
|
emit_mit_license(); |
158 |
|
emit_hline_std(); |
159 |
|
printf("This program accepts no command-line arguments and simply spawns a new thread\n"); |
160 |
|
printf("approximately every 1 second. The purpose of the program is to prevent\n"); |
161 |
|
printf("certain stalls that occur under Windows when running some programs/scripts\n"); |
162 |
|
printf("It is known that spawning a new thread periodically unstalls the programs/\n"); |
163 |
|
printf("scripts. The program can be terminated with CTRL-C or CTRL-BREAK.\n"); |
164 |
|
emit_hline_std(); |
165 |
|
|
166 |
|
SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE); |
167 |
|
//Yes, I know I'm supposed to check the return code. |
168 |
|
|
169 |
|
while (! ctrl_c_or_break_pressed) |
170 |
{ |
{ |
171 |
printf("Hello, world!\n"); |
//Backspace over the previous word. |
172 |
return 0; |
if (! first_time) |
173 |
|
{ |
174 |
|
//Beep(750, 500); |
175 |
|
|
176 |
|
for (ui = 0; ui < (strlen(kickish_words[selector]) + 1); ui++) |
177 |
|
{ |
178 |
|
printf("%c", (char)8); |
179 |
|
} |
180 |
|
for (ui = 0; ui < (strlen(kickish_words[selector]) + 1); ui++) |
181 |
|
{ |
182 |
|
printf(" "); |
183 |
|
} |
184 |
|
for (ui = 0; ui < (strlen(kickish_words[selector]) + 1); ui++) |
185 |
|
{ |
186 |
|
printf("%c", (char)8); |
187 |
|
} |
188 |
|
} |
189 |
|
|
190 |
|
first_time = 0; |
191 |
|
|
192 |
|
//Go to next string. |
193 |
|
if (selector < (NELEM(kickish_words) - 1)) |
194 |
|
selector++; |
195 |
|
else |
196 |
|
selector = 0; |
197 |
|
|
198 |
|
//Print the description. |
199 |
|
printf("%s!", kickish_words[selector]); |
200 |
|
|
201 |
|
//Start the thread. This will hopefully unstall things. |
202 |
|
thread_handle = CreateThread( |
203 |
|
NULL, // default security attributes |
204 |
|
0, // use default stack size |
205 |
|
MyThreadFunction, // thread function name |
206 |
|
0, // argument to thread function |
207 |
|
0, // use default creation flags |
208 |
|
&thread_id); // returns the thread identifier |
209 |
|
|
210 |
|
//If the create call failed, terminate. |
211 |
|
if (thread_handle == NULL) |
212 |
|
{ |
213 |
|
printf("\nOuch!\n"); |
214 |
|
exit(0); |
215 |
|
} |
216 |
|
|
217 |
|
//Wait for thread termination. This should be nearly instant. But it |
218 |
|
//would seem to be the best way to wait so as not to chew up CPU |
219 |
|
//cycles. |
220 |
|
WaitForSingleObject(thread_handle, INFINITE); |
221 |
|
|
222 |
|
//At this point, the thread should have run, and the variable should have been |
223 |
|
//set. If not, there is a real logical problem. |
224 |
|
if (!thread_ran) |
225 |
|
{ |
226 |
|
printf("\nDouble-ouch\n"); |
227 |
|
exit(0); |
228 |
|
} |
229 |
|
|
230 |
|
thread_ran = 0; |
231 |
|
|
232 |
|
//Delay. Sleep() is likely the most effective way to not waste CPU capacity. |
233 |
|
Sleep(1000); |
234 |
} |
} |
235 |
|
|
236 |
|
printf("\n"); |
237 |
|
emit_hline_std(); |
238 |
|
printf("Program terminated with CTRL-C or CTRL-BREAK.\n"); |
239 |
|
emit_hline_std(); |
240 |
|
|
241 |
|
return(0); |
242 |
|
} |
243 |
|
|
244 |
// End of c_main.c. |
// End of c_main.c. |