mirror of git://sourceware.org/git/glibc.git
stdio-common: In tst-setvbuf2, close helper thread descriptor only if opened
The helper thread may get canceled before the open system
call succeds. Then ThreadData.fd remains zero, and eventually
the xclose call in end_reader_thread fails because descriptor 0
is not open.
Instead, initialize the fd member to -1 (not a valid descriptor)
and close the descriptor only if valid. Do this in a new end_thread
helper routine.
Also add more error checking to close operations.
Fixes commit 95b780c1d0
("stdio: Add
more setvbuf tests").
This commit is contained in:
parent
fb3d821afa
commit
4fa959d13d
|
@ -240,6 +240,21 @@ typedef struct {
|
||||||
/* It's OK if this is static, we only run one at a time. */
|
/* It's OK if this is static, we only run one at a time. */
|
||||||
ThreadData thread_data;
|
ThreadData thread_data;
|
||||||
|
|
||||||
|
static void
|
||||||
|
end_thread (pthread_t *ptid)
|
||||||
|
{
|
||||||
|
if (*ptid)
|
||||||
|
{
|
||||||
|
pthread_cancel (*ptid);
|
||||||
|
xpthread_join (*ptid);
|
||||||
|
/* The descriptor was passed in, or the helper thread made
|
||||||
|
sufficient progress and opened the file. */
|
||||||
|
if (thread_data.fd >= 0)
|
||||||
|
xclose (thread_data.fd);
|
||||||
|
*ptid = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
writer_thread_proc (void *closure)
|
writer_thread_proc (void *closure)
|
||||||
{
|
{
|
||||||
|
@ -306,7 +321,7 @@ static void
|
||||||
start_writer_thread_n (const char *fname)
|
start_writer_thread_n (const char *fname)
|
||||||
{
|
{
|
||||||
debug;
|
debug;
|
||||||
thread_data.fd = 0;
|
thread_data.fd = -1;
|
||||||
thread_data.fname = fname;
|
thread_data.fname = fname;
|
||||||
writer_thread_tid = xpthread_create (NULL, writer_thread_proc,
|
writer_thread_tid = xpthread_create (NULL, writer_thread_proc,
|
||||||
(void *)&thread_data);
|
(void *)&thread_data);
|
||||||
|
@ -316,13 +331,7 @@ static void
|
||||||
end_writer_thread (void)
|
end_writer_thread (void)
|
||||||
{
|
{
|
||||||
debug;
|
debug;
|
||||||
if (writer_thread_tid)
|
end_thread (&writer_thread_tid);
|
||||||
{
|
|
||||||
pthread_cancel (writer_thread_tid);
|
|
||||||
xpthread_join (writer_thread_tid);
|
|
||||||
xclose (thread_data.fd);
|
|
||||||
writer_thread_tid = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -339,7 +348,7 @@ static void
|
||||||
start_reader_thread_n (const char *fname)
|
start_reader_thread_n (const char *fname)
|
||||||
{
|
{
|
||||||
debug;
|
debug;
|
||||||
thread_data.fd = 0;
|
thread_data.fd = -1;
|
||||||
thread_data.fname = fname;
|
thread_data.fname = fname;
|
||||||
reader_thread_tid = xpthread_create (NULL, reader_thread_proc,
|
reader_thread_tid = xpthread_create (NULL, reader_thread_proc,
|
||||||
(void *)&thread_data);
|
(void *)&thread_data);
|
||||||
|
@ -349,13 +358,7 @@ static void
|
||||||
end_reader_thread (void)
|
end_reader_thread (void)
|
||||||
{
|
{
|
||||||
debug;
|
debug;
|
||||||
if (reader_thread_tid)
|
end_thread (&reader_thread_tid);
|
||||||
{
|
|
||||||
pthread_cancel (reader_thread_tid);
|
|
||||||
xpthread_join (reader_thread_tid);
|
|
||||||
xclose (thread_data.fd);
|
|
||||||
reader_thread_tid = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------*/
|
/*------------------------------------------------------------*/
|
||||||
|
@ -852,7 +855,7 @@ do_second_part (FILE *fp,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fclose (fp);
|
xfclose (fp);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -939,7 +942,7 @@ recurse (FILE *fp,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: /* parent */
|
default: /* parent */
|
||||||
fclose (fp);
|
xfclose (fp);
|
||||||
xwaitpid (pid, &status, 0);
|
xwaitpid (pid, &status, 0);
|
||||||
if (WIFEXITED (status)
|
if (WIFEXITED (status)
|
||||||
&& WEXITSTATUS (status) == 0)
|
&& WEXITSTATUS (status) == 0)
|
||||||
|
|
Loading…
Reference in New Issue