Skip to content

Commit e0eb5c6

Browse files
Updates that allow accum SWMR tests to work on Windows (#493)
* Committing clang-format changes * Updates the accum test to work on Windows Uses CreateProcess() on Windows * Source formatting * Fix for Unix child result * Fixes process return code bug on Windows Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 6b13310 commit e0eb5c6

File tree

1 file changed

+102
-60
lines changed

1 file changed

+102
-60
lines changed

test/accum.c

+102-60
Original file line numberDiff line numberDiff line change
@@ -2074,13 +2074,14 @@ HDfprintf(stderr, "Random # seed was: %u\n", seed);
20742074
/*-------------------------------------------------------------------------
20752075
* Function: test_swmr_write_big
20762076
*
2077-
* Purpose: A SWMR test: verifies that writing "large" metadata to a file
2078-
* opened with SWMR_WRITE will flush the existing metadata in the
2079-
* accumulator to disk first before writing the "large" metadata
2080-
* to disk.
2081-
* This test will fork and exec a reader "accum_swmr_reader" which
2082-
* opens the same file with SWMR_READ and verifies that the correct
2083-
* metadata is read from disk.
2077+
* Purpose: A SWMR test: verifies that writing "large" metadata to a file
2078+
* opened with SWMR_WRITE will flush the existing metadata in the
2079+
* accumulator to disk first before writing the "large" metadata
2080+
* to disk.
2081+
*
2082+
* This test will fork and exec a reader "accum_swmr_reader" which
2083+
* opens the same file with SWMR_READ and verifies that the correct
2084+
* metadata is read from disk.
20842085
*
20852086
* Return: Success: 0
20862087
* Failure: 1
@@ -2092,24 +2093,31 @@ HDfprintf(stderr, "Random # seed was: %u\n", seed);
20922093
unsigned
20932094
test_swmr_write_big(hbool_t newest_format)
20942095
{
2095-
#ifdef H5_HAVE_UNISTD_H
2096+
20962097
hid_t fid = -1; /* File ID */
20972098
hid_t fapl = -1; /* File access property list */
20982099
H5F_t * rf = NULL; /* File pointer */
20992100
char filename[1024];
21002101
uint8_t *wbuf2 = NULL, *rbuf = NULL; /* Buffers for reading & writing */
21012102
uint8_t wbuf[1024]; /* Buffer for reading & writing */
21022103
unsigned u; /* Local index variable */
2103-
pid_t pid; /* Process ID */
2104-
int status; /* Status returned from child process */
2105-
char * driver = NULL; /* VFD string (from env variable) */
2106-
hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */
2104+
hbool_t process_success = FALSE;
2105+
char * driver = NULL; /* VFD string (from env variable) */
2106+
hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */
21072107

21082108
if (newest_format)
21092109
TESTING("SWMR write of large metadata: with latest format")
21102110
else
21112111
TESTING("SWMR write of large metadata: with non-latest-format")
21122112

2113+
#if !defined(H5_HAVE_UNISTD_H) && !defined(H5_HAVE_WIN32_API)
2114+
2115+
/* Not a Windows or POSIX system */
2116+
SKIPPED();
2117+
HDputs(" Test skipped: Not a Windows or POSIX system.");
2118+
return 0;
2119+
2120+
#else
21132121
/* Skip this test if SWMR I/O is not supported for the VFD specified
21142122
* by the environment variable.
21152123
*/
@@ -2219,56 +2227,94 @@ test_swmr_write_big(hbool_t newest_format)
22192227
if (HDmemcmp(wbuf2, rbuf, (size_t)BIG_BUF_SIZE) != 0)
22202228
TEST_ERROR;
22212229

2222-
/* Fork child process to verify that the data at [1024, 2014] does get written to disk */
2223-
if ((pid = HDfork()) < 0) {
2224-
HDperror("fork");
2225-
FAIL_STACK_ERROR;
2226-
}
2227-
else if (0 == pid) { /* Child process */
2228-
/* By convention, argv[0] tells the name of program invoked.
2229-
*
2230-
* execv on NetBSD 8 will actually return EFAULT if there is a
2231-
* NULL at argv[0], so we follow the convention unconditionally.
2232-
*/
2233-
char swmr_reader[] = SWMR_READER;
2234-
char *const new_argv[] = {swmr_reader, NULL};
2235-
/* Run the reader */
2236-
status = HDexecv(SWMR_READER, new_argv);
2237-
HDprintf("errno from execv = %s\n", HDstrerror(errno));
2238-
FAIL_STACK_ERROR;
2239-
} /* end if */
2230+
#if defined(H5_HAVE_WIN32_API)
2231+
{
2232+
STARTUPINFO si;
2233+
PROCESS_INFORMATION pi;
2234+
DWORD exit_code = EXIT_FAILURE;
22402235

2241-
/* Parent process -- wait for the child process to complete */
2242-
while (pid != HDwaitpid(pid, &status, 0))
2243-
/*void*/;
2236+
ZeroMemory(&si, sizeof(si));
2237+
si.cb = sizeof(si);
2238+
ZeroMemory(&pi, sizeof(pi));
22442239

2245-
/* Check if child process terminates normally and its return value */
2246-
if (WIFEXITED(status) && !WEXITSTATUS(status)) {
2247-
/* Flush the accumulator */
2248-
if (accum_reset(rf) < 0)
2240+
if (0 == CreateProcess(NULL, SWMR_READER, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
2241+
HDprintf("CreateProcess failed (%d).\n", GetLastError());
22492242
FAIL_STACK_ERROR;
2243+
}
22502244

2251-
/* Close and remove the file */
2252-
if (H5Fclose(fid) < 0)
2253-
FAIL_STACK_ERROR;
2245+
(void)WaitForSingleObject(pi.hProcess, INFINITE);
2246+
2247+
if (FALSE == GetExitCodeProcess(pi.hProcess, &exit_code) || EXIT_FAILURE == exit_code)
2248+
process_success = FALSE;
2249+
else
2250+
process_success = TRUE;
22542251

2255-
/* Close the property list */
2256-
if (H5Pclose(fapl) < 0)
2252+
CloseHandle(pi.hProcess);
2253+
CloseHandle(pi.hThread);
2254+
}
2255+
#else /* defined(H5_HAVE_WIN32_API) */
2256+
{
2257+
pid_t pid; /* Process ID */
2258+
int status; /* Status returned from child process */
2259+
2260+
/* Fork child process to verify that the data at [1024, 2014] does get written to disk */
2261+
if ((pid = HDfork()) < 0) {
2262+
HDperror("fork");
2263+
FAIL_STACK_ERROR;
2264+
}
2265+
else if (0 == pid) { /* Child process */
2266+
/* By convention, argv[0] tells the name of program invoked.
2267+
*
2268+
* execv on NetBSD 8 will actually return EFAULT if there is a
2269+
* NULL at argv[0], so we follow the convention unconditionally.
2270+
*/
2271+
char swmr_reader[] = SWMR_READER;
2272+
char *const new_argv[] = {swmr_reader, NULL};
2273+
/* Run the reader */
2274+
status = HDexecv(SWMR_READER, new_argv);
2275+
HDprintf("errno from execv = %s\n", HDstrerror(errno));
22572276
FAIL_STACK_ERROR;
2277+
} /* end if */
22582278

2259-
/* Pop API context */
2260-
if (api_ctx_pushed && H5CX_pop(FALSE) < 0)
2261-
FAIL_STACK_ERROR
2262-
api_ctx_pushed = FALSE;
2263-
2264-
/* Release memory */
2265-
if (wbuf2)
2266-
HDfree(wbuf2);
2267-
if (rbuf)
2268-
HDfree(rbuf);
2269-
PASSED();
2270-
return 0;
2271-
} /* end if */
2279+
/* Parent process -- wait for the child process to complete */
2280+
while (pid != HDwaitpid(pid, &status, 0))
2281+
/*void*/;
2282+
2283+
/* Check if child process terminates normally and its return value */
2284+
if (WIFEXITED(status) && !WEXITSTATUS(status))
2285+
process_success = TRUE;
2286+
}
2287+
#endif /* defined(H5_HAVE_WIN32_API) */
2288+
2289+
/* Check if the process terminated correctly */
2290+
if (!process_success)
2291+
FAIL_PUTS_ERROR("child process exited abnormally")
2292+
2293+
/* Flush the accumulator */
2294+
if (accum_reset(rf) < 0)
2295+
FAIL_STACK_ERROR;
2296+
2297+
/* Close and remove the file */
2298+
if (H5Fclose(fid) < 0)
2299+
FAIL_STACK_ERROR;
2300+
2301+
/* Close the property list */
2302+
if (H5Pclose(fapl) < 0)
2303+
FAIL_STACK_ERROR;
2304+
2305+
/* Pop API context */
2306+
if (api_ctx_pushed && H5CX_pop(FALSE) < 0)
2307+
FAIL_STACK_ERROR
2308+
api_ctx_pushed = FALSE;
2309+
2310+
/* Release memory */
2311+
if (wbuf2)
2312+
HDfree(wbuf2);
2313+
if (rbuf)
2314+
HDfree(rbuf);
2315+
2316+
PASSED();
2317+
return 0;
22722318

22732319
error:
22742320
/* Closing and remove the file */
@@ -2287,11 +2333,7 @@ test_swmr_write_big(hbool_t newest_format)
22872333

22882334
return 1;
22892335

2290-
#else /* H5_HAVE_UNISTD_H */
2291-
SKIPPED();
2292-
HDputs(" Test skipped due to fork, waitpid, or pid_t not defined.");
2293-
return 0;
2294-
#endif /* H5_HAVE_UNISTD_H */
2336+
#endif /* !defined(H5_HAVE_UNISTD_H) && !defined(H5_HAVE_WIN32_API) */
22952337

22962338
} /* end test_swmr_write_big() */
22972339

0 commit comments

Comments
 (0)