mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-22 13:00:06 +00:00
* sysdeps/pthread/aio_notify.c (notify_func_wrapper): Take a malloc'd
struct containing function ptr and value, free it. (__aio_notify_only): Allocate that and copy values from SIGEV into it. It's not safe to let the new thread use the SIGEV pointer.
This commit is contained in:
parent
531da978ce
commit
57b4cb2522
@ -1,3 +1,10 @@
|
|||||||
|
2002-12-08 Roland McGrath <roland@redhat.com>
|
||||||
|
|
||||||
|
* sysdeps/pthread/aio_notify.c (notify_func_wrapper): Take a malloc'd
|
||||||
|
struct containing function ptr and value, free it.
|
||||||
|
(__aio_notify_only): Allocate that and copy values from SIGEV into it.
|
||||||
|
It's not safe to let the new thread use the SIGEV pointer.
|
||||||
|
|
||||||
2001-10-20 Paul Eggert <eggert@twinsun.com>
|
2001-10-20 Paul Eggert <eggert@twinsun.com>
|
||||||
|
|
||||||
* misc/error.c (strerror_r): Do not declare unless [!_LIBC].
|
* misc/error.c (strerror_r): Do not declare unless [!_LIBC].
|
||||||
|
@ -25,11 +25,20 @@
|
|||||||
#include "aio_misc.h"
|
#include "aio_misc.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct notify_func
|
||||||
|
{
|
||||||
|
void (*func) (sigval_t);
|
||||||
|
sigval_t value;
|
||||||
|
};
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
notify_func_wrapper (void *arg)
|
notify_func_wrapper (void *arg)
|
||||||
{
|
{
|
||||||
struct sigevent *sigev = arg;
|
struct notify_func *const n = arg;
|
||||||
sigev->sigev_notify_function (sigev->sigev_value);
|
void (*func) (sigval_t) = n->func;
|
||||||
|
sigval_t value = n->value;
|
||||||
|
free (n);
|
||||||
|
(*func) (value);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,8 +64,26 @@ __aio_notify_only (struct sigevent *sigev, pid_t caller_pid)
|
|||||||
pattr = &attr;
|
pattr = &attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pthread_create (&tid, pattr, notify_func_wrapper, sigev) < 0)
|
/* SIGEV may be freed as soon as we return, so we cannot let the
|
||||||
|
notification thread use that pointer. Even though a sigval_t is
|
||||||
|
only one word and the same size as a void *, we cannot just pass
|
||||||
|
the value through pthread_create as the argument and have the new
|
||||||
|
thread run the user's function directly, because on some machines
|
||||||
|
the calling convention for a union like sigval_t is different from
|
||||||
|
that for a pointer type like void *. */
|
||||||
|
struct notify_func *nf = malloc (sizeof *nf);
|
||||||
|
if (nf == NULL)
|
||||||
result = -1;
|
result = -1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nf->func = sigev->sigev_notify_function;
|
||||||
|
nf->value = sigev->sigev_value;
|
||||||
|
if (pthread_create (&tid, pattr, notify_func_wrapper, nf) < 0)
|
||||||
|
{
|
||||||
|
free (nf);
|
||||||
|
result = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (sigev->sigev_notify == SIGEV_SIGNAL)
|
else if (sigev->sigev_notify == SIGEV_SIGNAL)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user