mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
pthreadpool: Test fork with an active thread
Bug: https://bugzilla.samba.org/show_bug.cgi?id=13006 Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org> Autobuild-User(master): Volker Lendecke <vl@samba.org> Autobuild-Date(master): Thu Aug 31 21:34:57 CEST 2017 on sn-devel-144
This commit is contained in:
parent
ff98e3fb66
commit
981e674a74
@ -7,6 +7,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include "pthreadpool_pipe.h"
|
||||
#include "pthreadpool_tevent.h"
|
||||
|
||||
@ -192,6 +193,113 @@ static int test_fork(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void busyfork_job(void *private_data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static int test_busyfork(void)
|
||||
{
|
||||
struct pthreadpool_pipe *p;
|
||||
int fds[2];
|
||||
struct pollfd pfd;
|
||||
pid_t child, waitret;
|
||||
int ret, jobnum, wstatus;
|
||||
|
||||
ret = pipe(fds);
|
||||
if (ret == -1) {
|
||||
perror("pipe failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = pthreadpool_pipe_init(1, &p);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "pthreadpool_pipe_init failed: %s\n",
|
||||
strerror(ret));
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = pthreadpool_pipe_add_job(p, 1, busyfork_job, NULL);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "pthreadpool_add_job failed: %s\n",
|
||||
strerror(ret));
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = pthreadpool_pipe_finished_jobs(p, &jobnum, 1);
|
||||
if (ret != 1) {
|
||||
fprintf(stderr, "pthreadpool_pipe_finished_jobs failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
poll(NULL, 0, 200);
|
||||
|
||||
child = fork();
|
||||
if (child < 0) {
|
||||
perror("fork failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (child == 0) {
|
||||
ret = pthreadpool_pipe_destroy(p);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "pthreadpool_pipe_destroy failed: "
|
||||
"%s\n", strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
ret = close(fds[1]);
|
||||
if (ret == -1) {
|
||||
perror("close failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pfd = (struct pollfd) { .fd = fds[0], .events = POLLIN };
|
||||
|
||||
ret = poll(&pfd, 1, 5000);
|
||||
if (ret == -1) {
|
||||
perror("poll failed");
|
||||
return -1;
|
||||
}
|
||||
if (ret == 0) {
|
||||
fprintf(stderr, "Child did not exit for 5 seconds\n");
|
||||
/*
|
||||
* The child might hang forever in
|
||||
* pthread_cond_destroy for example. Be kind to the
|
||||
* system and kill it.
|
||||
*/
|
||||
kill(child, SIGTERM);
|
||||
return -1;
|
||||
}
|
||||
if (ret != 1) {
|
||||
fprintf(stderr, "poll returned %d -- huh??\n", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
poll(NULL, 0, 200);
|
||||
|
||||
waitret = waitpid(child, &wstatus, WNOHANG);
|
||||
if (waitret != child) {
|
||||
fprintf(stderr, "waitpid returned %d\n", (int)waitret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!WIFEXITED(wstatus)) {
|
||||
fprintf(stderr, "child did not properly exit\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = WEXITSTATUS(wstatus);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "child returned %d\n", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_tevent_wait(void *private_data)
|
||||
{
|
||||
int *timeout = private_data;
|
||||
@ -301,6 +409,12 @@ int main(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = test_busyfork();
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "test_busyfork failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("success\n");
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user