Allow users to request a asynchronous notification
This patch adds functionality to request an asynchronous notification if some other process has send a message to it. We currently send a SIGALRM to avoid any changes to core infrastructure of signal handling. Ideally we should implement a separate signal for this. Currently there is an obvious disadvantage of not being able to use SIGALRM with alarm, if we are using this functionality.
This commit is contained in:
parent
55d341bc54
commit
8501cb7ed8
12 changed files with 93 additions and 2 deletions
|
@ -855,6 +855,7 @@ struct
|
||||||
{ "MQ_REC", SYS_MQ_REC},
|
{ "MQ_REC", SYS_MQ_REC},
|
||||||
{ "MQ_SET_ATTR", SYS_MQ_SET_ATTR},
|
{ "MQ_SET_ATTR", SYS_MQ_SET_ATTR},
|
||||||
{ "MQ_GET_ATTR", SYS_MQ_GET_ATTR},
|
{ "MQ_GET_ATTR", SYS_MQ_GET_ATTR},
|
||||||
|
{ "MQ_REQ_NOTIFY", SYS_MQ_REQ_NOTIFY},
|
||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -268,9 +268,10 @@
|
||||||
# define SYS_MQ_REC (KERNEL_CALL + 61) /* sys_mq_rec */
|
# define SYS_MQ_REC (KERNEL_CALL + 61) /* sys_mq_rec */
|
||||||
# define SYS_MQ_SET_ATTR (KERNEL_CALL + 62) /* sys_mq_set_attributes */
|
# define SYS_MQ_SET_ATTR (KERNEL_CALL + 62) /* sys_mq_set_attributes */
|
||||||
# define SYS_MQ_GET_ATTR (KERNEL_CALL + 63) /* sys_mq_get_attributes */
|
# define SYS_MQ_GET_ATTR (KERNEL_CALL + 63) /* sys_mq_get_attributes */
|
||||||
|
# define SYS_MQ_REQ_NOTIFY (KERNEL_CALL + 64) /* sys_mq_request_notify */
|
||||||
|
|
||||||
/* Total */
|
/* Total */
|
||||||
#define NR_SYS_CALLS 64 /* number of kernel calls */
|
#define NR_SYS_CALLS 65 /* number of kernel calls */
|
||||||
|
|
||||||
#define SYS_CALL_MASK_SIZE BITMAP_CHUNKS(NR_SYS_CALLS)
|
#define SYS_CALL_MASK_SIZE BITMAP_CHUNKS(NR_SYS_CALLS)
|
||||||
|
|
||||||
|
|
|
@ -1273,6 +1273,13 @@ typedef struct {
|
||||||
} mess_lsys_krn_sys_mqueue_attribute;
|
} mess_lsys_krn_sys_mqueue_attribute;
|
||||||
_ASSERT_MSG_SIZE(mess_lsys_krn_sys_mqueue_attribute);
|
_ASSERT_MSG_SIZE(mess_lsys_krn_sys_mqueue_attribute);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int notify_on_off;
|
||||||
|
|
||||||
|
uint8_t padding[52];
|
||||||
|
} mess_lsys_krn_sys_mqueue_notify;
|
||||||
|
_ASSERT_MSG_SIZE(mess_lsys_krn_sys_mqueue_notify);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *vec_addr;
|
void *vec_addr;
|
||||||
int vec_size;
|
int vec_size;
|
||||||
|
@ -2295,6 +2302,7 @@ typedef struct noxfer_message {
|
||||||
mess_lsys_krn_sys_mqueue_send m_lsys_krn_sys_mqueue_send;
|
mess_lsys_krn_sys_mqueue_send m_lsys_krn_sys_mqueue_send;
|
||||||
mess_lsys_krn_sys_mqueue_receive m_lsys_krn_sys_mqueue_receive;
|
mess_lsys_krn_sys_mqueue_receive m_lsys_krn_sys_mqueue_receive;
|
||||||
mess_lsys_krn_sys_mqueue_attribute m_lsys_krn_sys_mqueue_attribute;
|
mess_lsys_krn_sys_mqueue_attribute m_lsys_krn_sys_mqueue_attribute;
|
||||||
|
mess_lsys_krn_sys_mqueue_notify m_lsys_krn_sys_mqueue_notify;
|
||||||
|
|
||||||
u8_t size[56]; /* message payload may have 56 bytes at most */
|
u8_t size[56]; /* message payload may have 56 bytes at most */
|
||||||
};
|
};
|
||||||
|
|
|
@ -281,6 +281,7 @@ int sys_mq_receive(int mqdes, char *msg_ptr, unsigned int msg_prio);
|
||||||
int sys_mq_get_attr(int *no_of_messages, int *no_of_queues, int *blocking);
|
int sys_mq_get_attr(int *no_of_messages, int *no_of_queues, int *blocking);
|
||||||
int sys_mq_set_attr(int no_of_messages, int no_of_queues, int blocking);
|
int sys_mq_set_attr(int no_of_messages, int no_of_queues, int blocking);
|
||||||
int sys_mq_close(int mqdes);
|
int sys_mq_close(int mqdes);
|
||||||
|
int sys_mq_request_notify(int notify_on_off);
|
||||||
int sys_endpoint_from_pid(pid_t pid, endpoint_t *endpoint);
|
int sys_endpoint_from_pid(pid_t pid, endpoint_t *endpoint);
|
||||||
|
|
||||||
#endif /* _SYSLIB_H */
|
#endif /* _SYSLIB_H */
|
||||||
|
|
|
@ -21,6 +21,7 @@ int initialize_message_queues(void)
|
||||||
number_of_queues = MAX_QUEUES;
|
number_of_queues = MAX_QUEUES;
|
||||||
number_of_messages = MAX_MESSAGES;
|
number_of_messages = MAX_MESSAGES;
|
||||||
mq_blocking = MQ_NON_BLOCKING;
|
mq_blocking = MQ_NON_BLOCKING;
|
||||||
|
notify = NOTIFY_OFF;
|
||||||
|
|
||||||
for (int i = 0; i < number_of_queues; i++) {
|
for (int i = 0; i < number_of_queues; i++) {
|
||||||
mq.queue_slot_empty[i] = EMPTY;
|
mq.queue_slot_empty[i] = EMPTY;
|
||||||
|
@ -154,6 +155,21 @@ int mq_send(mqd_t mqdes, const char *msg_ptr, unsigned int msg_prio, endpoint_t
|
||||||
mq.msg[mqdes].msge[empty_slot_pos].timestamp = get_monotonic();
|
mq.msg[mqdes].msge[empty_slot_pos].timestamp = get_monotonic();
|
||||||
mq.msg[mqdes].num_msgs++;
|
mq.msg[mqdes].num_msgs++;
|
||||||
|
|
||||||
|
if (notify) {
|
||||||
|
proc_nr_t proc_nr;
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_RECEIVERS; i++) {
|
||||||
|
if (dst[i] != -1) {
|
||||||
|
/* Translate endpoint to process number */
|
||||||
|
if (!isokendpt(dst[i], &proc_nr))
|
||||||
|
goto exit;
|
||||||
|
else
|
||||||
|
cause_sig(proc_nr, SIGALRM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,3 +245,13 @@ int clean_message_queue(mqd_t mqdes)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mq_notify(int notify_on_off)
|
||||||
|
{
|
||||||
|
if (notify_on_off)
|
||||||
|
notify = NOTIFY_ON;
|
||||||
|
else
|
||||||
|
notify = NOTIFY_OFF;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -29,6 +29,9 @@
|
||||||
#define MQ_BLOCKING 0
|
#define MQ_BLOCKING 0
|
||||||
#define MQ_NON_BLOCKING 1
|
#define MQ_NON_BLOCKING 1
|
||||||
|
|
||||||
|
#define NOTIFY_ON 1
|
||||||
|
#define NOTIFY_OFF 0
|
||||||
|
|
||||||
typedef int mqd_t;
|
typedef int mqd_t;
|
||||||
|
|
||||||
typedef struct message_entity {
|
typedef struct message_entity {
|
||||||
|
@ -56,6 +59,7 @@ typedef struct message_queue {
|
||||||
int number_of_messages;
|
int number_of_messages;
|
||||||
int number_of_queues;
|
int number_of_queues;
|
||||||
int mq_blocking;
|
int mq_blocking;
|
||||||
|
int notify;
|
||||||
|
|
||||||
int initialize_message_queues(void);
|
int initialize_message_queues(void);
|
||||||
int deinitialize_message_queues(void);
|
int deinitialize_message_queues(void);
|
||||||
|
@ -66,6 +70,7 @@ size_t mq_receive(mqd_t mqdes, char *msg_ptr, unsigned int msg_prio, endpoint_t
|
||||||
int mq_get_attributes(int *no_of_msgs, int *no_of_queues, int *blocking);
|
int mq_get_attributes(int *no_of_msgs, int *no_of_queues, int *blocking);
|
||||||
int mq_set_attributes(int no_of_msgs, int no_of_queues, int blocking);
|
int mq_set_attributes(int no_of_msgs, int no_of_queues, int blocking);
|
||||||
int mq_close(mqd_t mqdes);
|
int mq_close(mqd_t mqdes);
|
||||||
|
int mq_notify(int notify_on_off);
|
||||||
|
|
||||||
int clean_message_queue(mqd_t mqdes);
|
int clean_message_queue(mqd_t mqdes);
|
||||||
int message_index_with_highprio(mqd_t mqdes, endpoint_t dst);
|
int message_index_with_highprio(mqd_t mqdes, endpoint_t dst);
|
||||||
|
|
|
@ -275,6 +275,7 @@ void system_init(void)
|
||||||
map(SYS_MQ_REC, do_mq_rec); /* receive from a message queue */
|
map(SYS_MQ_REC, do_mq_rec); /* receive from a message queue */
|
||||||
map(SYS_MQ_SET_ATTR, do_mq_set_attr); /* set message queue attributes */
|
map(SYS_MQ_SET_ATTR, do_mq_set_attr); /* set message queue attributes */
|
||||||
map(SYS_MQ_GET_ATTR, do_mq_get_attr); /* get message queue attributes */
|
map(SYS_MQ_GET_ATTR, do_mq_get_attr); /* get message queue attributes */
|
||||||
|
map(SYS_MQ_REQ_NOTIFY, do_mq_request_notify); /* request notification for receive */
|
||||||
|
|
||||||
}
|
}
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
|
|
|
@ -236,5 +236,10 @@ int do_mq_get_attr(struct proc * caller, message *m_ptr);
|
||||||
#define do_mq_get_attr NULL
|
#define do_mq_get_attr NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int do_mq_request_notify(struct proc * caller, message *m_ptr);
|
||||||
|
#if ! USE_MQ_IPC
|
||||||
|
#define do_mq_request_notify NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* SYSTEM_H */
|
#endif /* SYSTEM_H */
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,8 @@ SRCS+= \
|
||||||
do_mq_send.c \
|
do_mq_send.c \
|
||||||
do_mq_rec.c \
|
do_mq_rec.c \
|
||||||
do_mq_set_attribute.c \
|
do_mq_set_attribute.c \
|
||||||
do_mq_get_attribute.c
|
do_mq_get_attribute.c \
|
||||||
|
do_mq_request_notify.c
|
||||||
|
|
||||||
.if ${MACHINE_ARCH} == "i386"
|
.if ${MACHINE_ARCH} == "i386"
|
||||||
SRCS+= \
|
SRCS+= \
|
||||||
|
|
26
minix/kernel/system/do_mq_request_notify.c
Normal file
26
minix/kernel/system/do_mq_request_notify.c
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/* The kernel call implemented in this file:
|
||||||
|
* m_type: SYS_MQ_REQUEST_NOTIFY
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "kernel/mqueue.h"
|
||||||
|
#include "kernel/system.h"
|
||||||
|
#include "kernel/vm.h"
|
||||||
|
#include <signal.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <minix/endpoint.h>
|
||||||
|
#include <minix/u64.h>
|
||||||
|
|
||||||
|
#if USE_MQ_IPC
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* do_mq_request_notify *
|
||||||
|
*===========================================================================*/
|
||||||
|
int do_mq_request_notify(struct proc * caller, message * m_ptr)
|
||||||
|
{
|
||||||
|
return mq_notify(m_ptr->m_lsys_krn_sys_mqueue_notify.notify_on_off);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* USE_MQ_IPC */
|
|
@ -94,6 +94,7 @@ SRCS+= \
|
||||||
sys_mq_receive.c \
|
sys_mq_receive.c \
|
||||||
sys_mq_set_attr.c \
|
sys_mq_set_attr.c \
|
||||||
sys_mq_get_attr.c \
|
sys_mq_get_attr.c \
|
||||||
|
sys_mq_request_notify.c \
|
||||||
sys_endpoint_from_pid.c \
|
sys_endpoint_from_pid.c \
|
||||||
taskcall.c \
|
taskcall.c \
|
||||||
tickdelay.c \
|
tickdelay.c \
|
||||||
|
|
15
minix/lib/libsys/sys_mq_request_notify.c
Normal file
15
minix/lib/libsys/sys_mq_request_notify.c
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#include "syslib.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <machine/archtypes.h>
|
||||||
|
#include <minix/timers.h>
|
||||||
|
#include <minix/sysutil.h>
|
||||||
|
#include <minix/vm.h>
|
||||||
|
|
||||||
|
int sys_mq_request_notify(int notify_on_off)
|
||||||
|
{
|
||||||
|
message m;
|
||||||
|
|
||||||
|
m.m_lsys_krn_sys_mqueue_notify.notify_on_off = notify_on_off;
|
||||||
|
|
||||||
|
return (_kernel_call(SYS_MQ_REQ_NOTIFY, &m));
|
||||||
|
}
|
Loading…
Reference in a new issue