4 #include <sys/socket.h>
15 const struct sigevent
*sev
;
18 static void *start(void *p
)
20 struct args
*args
= p
;
24 void (*func
)(union sigval
) = args
->sev
->sigev_notify_function
;
25 union sigval val
= args
->sev
->sigev_value
;
27 static const char zeros
[32];
30 sev2
.sigev_notify
= SIGEV_THREAD
;
32 sev2
.sigev_value
.sival_ptr
= (void *)&zeros
;
34 args
->err
= err
= -__syscall(SYS_mq_notify
, args
->mqd
, &sev2
);
38 pthread_detach(pthread_self());
39 n
= recv(s
, buf
, sizeof(buf
), MSG_NOSIGNAL
|MSG_WAITALL
);
41 if (n
==sizeof buf
&& buf
[sizeof buf
- 1] == 1)
46 int mq_notify(mqd_t mqd
, const struct sigevent
*sev
)
48 struct args args
= { .sev
= sev
};
53 sigset_t allmask
, origmask
;
55 if (!sev
|| sev
->sigev_notify
!= SIGEV_THREAD
)
56 return syscall(SYS_mq_notify
, mqd
, sev
);
58 s
= socket(AF_NETLINK
, SOCK_RAW
|SOCK_CLOEXEC
, 0);
63 if (sev
->sigev_notify_attributes
) attr
= *sev
->sigev_notify_attributes
;
64 else pthread_attr_init(&attr
);
65 pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_JOINABLE
);
66 sem_init(&args
.sem
, 0, 0);
69 pthread_sigmask(SIG_BLOCK
, &allmask
, &origmask
);
70 if (pthread_create(&td
, &attr
, start
, &args
)) {
71 __syscall(SYS_close
, s
);
72 pthread_sigmask(SIG_SETMASK
, &origmask
, 0);
76 pthread_sigmask(SIG_SETMASK
, &origmask
, 0);
78 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, &cs
);
80 sem_destroy(&args
.sem
);
83 __syscall(SYS_close
, s
);
85 pthread_setcancelstate(cs
, 0);
90 pthread_setcancelstate(cs
, 0);