| /* This is a test case where the parent process forks 10 children |
| * which contend to merge profile data to the same file. With |
| * file locking support, the data from each child should not |
| * be lost. |
| */ |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <windows.h> |
| |
| void spawn_child(PROCESS_INFORMATION *pi, int child_num) { |
| wchar_t child_str[10]; |
| _itow(child_num, child_str, 10); |
| if (!SetEnvironmentVariableW(L"CHILD_NUM", child_str)) { |
| printf("SetEnvironmentVariableW failed (0x%8lx).\n", GetLastError()); |
| fflush(stdout); |
| exit(1); |
| } |
| |
| STARTUPINFOW si; |
| memset(&si, 0, sizeof(si)); |
| si.cb = sizeof(si); |
| |
| memset(pi, 0, sizeof(PROCESS_INFORMATION)); |
| |
| if (!CreateProcessW(NULL, // No module name (use command line) |
| GetCommandLineW(), // Command line |
| NULL, // Process handle not inheritable |
| NULL, // Thread handle not inheritable |
| TRUE, // Set handle inheritance to TRUE |
| 0, // No flags |
| NULL, // Use parent's environment block |
| NULL, // Use parent's starting directory |
| &si, pi)) { |
| printf("CreateProcess failed (0x%08lx).\n", GetLastError()); |
| fflush(stdout); |
| exit(1); |
| } |
| } |
| |
| int wait_child(PROCESS_INFORMATION *pi) { |
| WaitForSingleObject(pi->hProcess, INFINITE); |
| |
| DWORD exit_code; |
| if (!GetExitCodeProcess(pi->hProcess, &exit_code)) { |
| printf("GetExitCodeProcess failed (0x%08lx).\n", GetLastError()); |
| fflush(stdout); |
| exit(1); |
| } |
| |
| CloseHandle(pi->hProcess); |
| CloseHandle(pi->hThread); |
| |
| return exit_code; |
| } |
| |
| #define NUM_CHILDREN 10 |
| |
| int foo(int num) { |
| if (num < (NUM_CHILDREN / 2)) { |
| return 1; |
| } else if (num < NUM_CHILDREN) { |
| return 2; |
| } |
| return 3; |
| } |
| |
| int main(int argc, char *argv[]) { |
| char *child_str = getenv("CHILD_NUM"); |
| if (!child_str) { |
| PROCESS_INFORMATION child[NUM_CHILDREN]; |
| // In parent |
| for (int i = 0; i < NUM_CHILDREN; i++) { |
| spawn_child(&child[i], i); |
| } |
| for (int i = 0; i < NUM_CHILDREN; i++) { |
| wait_child(&child[i]); |
| } |
| return 0; |
| } else { |
| // In child |
| int child_num = atoi(child_str); |
| int result = foo(child_num); |
| if (result == 3) { |
| fprintf(stderr, "Invalid child count!"); |
| return 1; |
| } |
| return 0; |
| } |
| } |