Last active
June 27, 2016 15:38
-
-
Save lmb/17a528cdadde73fb231a2a1ed84714f7 to your computer and use it in GitHub Desktop.
Test case for mdb_env_copyfd2 deadlock
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2012 Howard Chu, Symas Corp. | |
* All rights reserved. | |
* | |
* Redistribution and use in source and binary forms, with or without | |
* modification, are permitted only as authorized by the OpenLDAP | |
* Public License. | |
* | |
* A copy of this license is available in the file LICENSE in the | |
* top-level directory of the distribution or, alternatively, at | |
* <http://www.OpenLDAP.org/license.html>. | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <pthread.h> | |
#include <errno.h> | |
#include <signal.h> | |
#include "lmdb.h" | |
struct copyinfo { | |
MDB_env *env; | |
int fd; | |
}; | |
static void * | |
copythr(void *arg) | |
{ | |
struct copyinfo *ci = (struct copyinfo*)arg; | |
MDB_env *env = (MDB_env*)arg; | |
int rc; | |
rc = mdb_env_copyfd2(ci->env, ci->fd, MDB_CP_COMPACT); | |
return (void*)rc; | |
} | |
int main(int argc,char * argv[]) | |
{ | |
int rc, copy_rc; | |
MDB_env *env; | |
int pipefd[2]; | |
sigset_t set; | |
pthread_t pid; | |
struct copyinfo ci; | |
#define check(rc, x) rc = x; if (rc) { fprintf(stderr, #x ": (%d) %s\n", rc, mdb_strerror(rc)); goto leave; } | |
sigemptyset(&set); | |
sigaddset(&set, SIGPIPE); | |
rc = pthread_sigmask(SIG_BLOCK, &set, NULL); | |
if (rc) { | |
return 1; | |
} | |
if (pipe(pipefd) != 0) { | |
return errno; | |
} | |
check(rc, mdb_env_create(&env)); | |
check(rc, mdb_env_open(env, "./", 0, 0664)); | |
ci.env = env; | |
ci.fd = pipefd[1]; | |
rc = pthread_create(&pid, NULL, ©thr, &ci); | |
if (rc) { | |
goto leave; | |
} | |
close(pipefd[0]); | |
rc = pthread_join(pid, ©_rc); | |
if (rc) { | |
goto leave; | |
} | |
if (copy_rc != EPIPE) { | |
fprintf(stderr, "mdb_env_copyfd2 did not return EPIPE but %d\n", copy_rc); | |
rc = 1; | |
} else { | |
fprintf(stderr, "mdb_env_copyfd2 returned EPIPE\n"); | |
rc = 0; | |
} | |
leave: | |
mdb_env_close(env); | |
return rc; | |
#undef check | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Compile using