struct msg_msg **messages;
struct mq_attr attr;
- struct sigevent notify; /* notify.sigev_notify == SIGEV_NONE means */
- pid_t notify_owner; /* no notification registered */
+ struct sigevent notify;
+ pid_t notify_owner;
struct sock *notify_sock;
struct sk_buff *notify_cookie;
init_waitqueue_head(&info->wait_q);
INIT_LIST_HEAD(&info->e_wait_q[0].list);
INIT_LIST_HEAD(&info->e_wait_q[1].list);
- info->notify.sigev_notify = SIGEV_NONE;
+ info->notify_owner = 0;
info->qsize = 0;
memset(&info->attr, 0, sizeof(info->attr));
info->attr.mq_maxmsg = DFLT_MSGMAX;
snprintf(buffer, sizeof(buffer),
"QSIZE:%-10lu NOTIFY:%-5d SIGNO:%-5d NOTIFY_PID:%-6d\n",
info->qsize,
- info->notify.sigev_notify,
- (info->notify.sigev_notify == SIGEV_SIGNAL ) ?
+ info->notify_owner ? info->notify.sigev_notify : 0,
+ (info->notify_owner &&
+ info->notify.sigev_notify == SIGEV_SIGNAL) ?
info->notify.sigev_signo : 0,
- (info->notify.sigev_notify != SIGEV_NONE) ?
- info->notify_owner : 0);
+ info->notify_owner);
spin_unlock(&info->lock);
buffer[sizeof(buffer)-1] = '\0';
slen = strlen(buffer)+1;
struct mqueue_inode_info *info = MQUEUE_I(filp->f_dentry->d_inode);
spin_lock(&info->lock);
- if (info->notify.sigev_notify != SIGEV_NONE &&
- current->tgid == info->notify_owner)
+ if (current->tgid == info->notify_owner)
remove_notification(info);
spin_unlock(&info->lock);
* waiting synchronously for message AND state of queue changed from
* empty to not empty. Here we are sure that no one is waiting
* synchronously. */
- if (info->notify.sigev_notify != SIGEV_NONE &&
- info->attr.mq_curmsgs == 1) {
- /* sends signal */
- if (info->notify.sigev_notify == SIGEV_SIGNAL) {
- struct siginfo sig_i;
+ if (info->notify_owner &&
+ info->attr.mq_curmsgs == 1) {
+ struct siginfo sig_i;
+ switch (info->notify.sigev_notify) {
+ case SIGEV_NONE:
+ break;
+ case SIGEV_SIGNAL:
+ /* sends signal */
sig_i.si_signo = info->notify.sigev_signo;
sig_i.si_errno = 0;
kill_proc_info(info->notify.sigev_signo,
&sig_i, info->notify_owner);
- } else if (info->notify.sigev_notify == SIGEV_THREAD) {
+ break;
+ case SIGEV_THREAD:
set_cookie(info->notify_cookie, NOTIFY_WOKENUP);
netlink_sendskb(info->notify_sock,
info->notify_cookie, 0);
+ break;
}
/* after notification unregisters process */
- info->notify.sigev_notify = SIGEV_NONE;
+ info->notify_owner = 0;
}
wake_up(&info->wait_q);
}
static void remove_notification(struct mqueue_inode_info *info)
{
- if (info->notify.sigev_notify == SIGEV_THREAD) {
+ if (info->notify_owner != 0 &&
+ info->notify.sigev_notify == SIGEV_THREAD) {
set_cookie(info->notify_cookie, NOTIFY_REMOVED);
netlink_sendskb(info->notify_sock, info->notify_cookie, 0);
}
- info->notify.sigev_notify = SIGEV_NONE;
+ info->notify_owner = 0;
}
/*
}
/*
- * Notes: the case when user wants us to deregister (with NULL as pointer
- * or SIGEV_NONE) and he isn't currently owner of notification will be
- * silently discarded. It isn't explicitly defined in the POSIX.
+ * Notes: the case when user wants us to deregister (with NULL as pointer)
+ * and he isn't currently owner of notification, will be silently discarded.
+ * It isn't explicitly defined in the POSIX.
*/
asmlinkage long sys_mq_notify(mqd_t mqdes,
const struct sigevent __user *u_notification)
nc = NULL;
sock = NULL;
- if (u_notification == NULL) {
- notification.sigev_notify = SIGEV_NONE;
- } else {
+ if (u_notification != NULL) {
if (copy_from_user(¬ification, u_notification,
sizeof(struct sigevent)))
return -EFAULT;
ret = 0;
spin_lock(&info->lock);
- switch (notification.sigev_notify) {
- case SIGEV_NONE:
- if (info->notify.sigev_notify != SIGEV_NONE &&
- info->notify_owner == current->tgid) {
+ if (u_notification == NULL) {
+ if (info->notify_owner == current->tgid) {
remove_notification(info);
inode->i_atime = inode->i_ctime = CURRENT_TIME;
}
- break;
- case SIGEV_THREAD:
- if (info->notify.sigev_notify != SIGEV_NONE) {
- ret = -EBUSY;
+ } else if (info->notify_owner != 0) {
+ ret = -EBUSY;
+ } else {
+ switch (notification.sigev_notify) {
+ case SIGEV_NONE:
+ info->notify.sigev_notify = SIGEV_NONE;
break;
- }
- info->notify_sock = sock;
- info->notify_cookie = nc;
- sock = NULL;
- nc = NULL;
- info->notify.sigev_notify = SIGEV_THREAD;
- info->notify_owner = current->tgid;
- inode->i_atime = inode->i_ctime = CURRENT_TIME;
- break;
- case SIGEV_SIGNAL:
- if (info->notify.sigev_notify != SIGEV_NONE) {
- ret = -EBUSY;
+ case SIGEV_THREAD:
+ info->notify_sock = sock;
+ info->notify_cookie = nc;
+ sock = NULL;
+ nc = NULL;
+ info->notify.sigev_notify = SIGEV_THREAD;
+ break;
+ case SIGEV_SIGNAL:
+ info->notify.sigev_signo = notification.sigev_signo;
+ info->notify.sigev_value = notification.sigev_value;
+ info->notify.sigev_notify = SIGEV_SIGNAL;
break;
}
- info->notify.sigev_signo = notification.sigev_signo;
- info->notify.sigev_value = notification.sigev_value;
- info->notify.sigev_notify = SIGEV_SIGNAL;
info->notify_owner = current->tgid;
inode->i_atime = inode->i_ctime = CURRENT_TIME;
}