diff options
Diffstat (limited to 'src/mq/mq_notify.c')
-rw-r--r-- | src/mq/mq_notify.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/src/mq/mq_notify.c b/src/mq/mq_notify.c index a42888d2..217d8888 100644 --- a/src/mq/mq_notify.c +++ b/src/mq/mq_notify.c @@ -10,6 +10,8 @@ struct args { sem_t sem; int sock; + mqd_t mqd; + int err; const struct sigevent *sev; }; @@ -21,8 +23,18 @@ static void *start(void *p) int s = args->sock; void (*func)(union sigval) = args->sev->sigev_notify_function; union sigval val = args->sev->sigev_value; + struct sigevent sev2; + static const char zeros[32]; + int err; + sev2.sigev_notify = SIGEV_THREAD; + sev2.sigev_signo = s; + sev2.sigev_value.sival_ptr = (void *)&zeros; + + args->err = err = -__syscall(SYS_mq_notify, args->mqd, &sev2); sem_post(&args->sem); + if (err) return 0; + n = recv(s, buf, sizeof(buf), MSG_NOSIGNAL|MSG_WAITALL); close(s); if (n==sizeof buf && buf[sizeof buf - 1] == 1) @@ -36,8 +48,6 @@ int mq_notify(mqd_t mqd, const struct sigevent *sev) pthread_attr_t attr; pthread_t td; int s; - struct sigevent sev2; - static const char zeros[32]; int cs; if (!sev || sev->sigev_notify != SIGEV_THREAD) @@ -46,6 +56,7 @@ int mq_notify(mqd_t mqd, const struct sigevent *sev) s = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, 0); if (s < 0) return -1; args.sock = s; + args.mqd = mqd; if (sev->sigev_notify_attributes) attr = *sev->sigev_notify_attributes; else pthread_attr_init(&attr); @@ -63,13 +74,9 @@ int mq_notify(mqd_t mqd, const struct sigevent *sev) pthread_setcancelstate(cs, 0); sem_destroy(&args.sem); - sev2.sigev_notify = SIGEV_THREAD; - sev2.sigev_signo = s; - sev2.sigev_value.sival_ptr = (void *)&zeros; - - if (syscall(SYS_mq_notify, mqd, &sev2) < 0) { - pthread_cancel(td); + if (args.err) { __syscall(SYS_close, s); + errno = args.err; return -1; } |