#include "unittest.h"
static void
test_reopen(const char *path)
{
PMEMblkpool *blk1 = pmemblk_create(path, 4096, PMEMBLK_MIN_POOL,
S_IWUSR | S_IRUSR);
if (!blk1)
UT_FATAL("!create");
PMEMblkpool *blk2 = pmemblk_open(path, 4096);
if (blk2)
UT_FATAL("pmemblk_open should not succeed");
if (errno != EWOULDBLOCK)
UT_FATAL("!pmemblk_open failed but for unexpected reason");
pmemblk_close(blk1);
blk2 = pmemblk_open(path, 4096);
if (!blk2)
UT_FATAL("pmemobj_open should succeed after close");
pmemblk_close(blk2);
UNLINK(path);
}
#ifndef _WIN32
static void
test_open_in_different_process(int argc, char **argv, int sleep)
{
pid_t pid = fork();
PMEMblkpool *blk;
char *path = argv[1];
if (pid < 0)
UT_FATAL("fork failed");
if (pid == 0) {
if (sleep)
usleep(sleep);
while (os_access(path, R_OK))
usleep(100 * 1000);
blk = pmemblk_open(path, 4096);
if (blk)
UT_FATAL("pmemblk_open after fork should not succeed");
if (errno != EWOULDBLOCK)
UT_FATAL("!pmemblk_open after fork failed but for "
"unexpected reason");
exit(0);
}
blk = pmemblk_create(path, 4096, PMEMBLK_MIN_POOL,
S_IWUSR | S_IRUSR);
if (!blk)
UT_FATAL("!create");
int status;
if (waitpid(pid, &status, 0) < 0)
UT_FATAL("!waitpid failed");
if (!WIFEXITED(status))
UT_FATAL("child process failed");
pmemblk_close(blk);
UNLINK(path);
}
#else
static void
test_open_in_different_process(int argc, char **argv, int sleep)
{
PMEMblkpool *blk;
if (sleep > 0)
return;
char *path = argv[1];
blk = pmemblk_create(path, 4096, PMEMBLK_MIN_POOL,
S_IWUSR | S_IRUSR);
if (!blk)
UT_FATAL("!create");
uintptr_t result = ut_spawnv(argc, argv, "X", NULL);
if (result != 0)
UT_FATAL("Create new process failed error: %d", GetLastError());
pmemblk_close(blk);
}
#endif
int
main(int argc, char *argv[])
{
START(argc, argv, "blk_pool_lock");
if (argc < 2)
UT_FATAL("usage: %s path", argv[0]);
if (argc == 2) {
test_reopen(argv[1]);
test_open_in_different_process(argc, argv, 0);
for (int i = 1; i < 100000; i *= 2)
test_open_in_different_process(argc, argv, i);
} else if (argc == 3) {
PMEMblkpool *blk;
blk = pmemblk_open(argv[1], 4096);
if (blk)
UT_FATAL("pmemblk_open after create process should "
"not succeed");
if (errno != EWOULDBLOCK)
UT_FATAL("!pmemblk_open after create process failed "
"but for unexpected reason");
}
DONE(NULL);
}