public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Jean-Christian de Rivaz <jcdr@lightning.ch>
To: linux-kernel@vger.kernel.org
Subject: [RFC][PATCH]/dev/ipc/* to poll a message
Date: Mon, 03 Dec 2001 18:21:20 +0100	[thread overview]
Message-ID: <3C0BB490.AE523828@lightning.ch> (raw)

Hi all,

This patch show a possibiliy to add a device per IPC message queue in
order to use the poll() or select() call. The goal is to have a easy way
in an application to wait on a IPC message in it main loop. This is just
to try and to have some code to talk about. Follow the patch and samples
applications.

Future work can be:
	- debug :-)
	- Config.in to controle CONFIG_IPC_DEV.
	- removing device on ipcrm.
	- ioctl to control type and mode of message to wait.
	- read methode to replace msgrcv() ?
	- write methode to replace msgsnd() ?
	- speciale device (like /dev/ppp) to replace msgget() ?
	- ...

Any comment ?

=== kernel patch =====================================================

--- ipc/msg.c   2001/10/03 09:03:38     1.1.1.13
+++ ipc/msg.c   2001/12/03 15:57:37
@@ -15,6 +15,8 @@
  * (c) 1999 Manfred Spraul <manfreds@colorfullife.com>
  */
 
+#define CONFIG_IPC_DEV
+
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <linux/msg.h>
@@ -24,6 +26,10 @@
 #include <linux/list.h>
 #include <asm/uaccess.h>
 #include "util.h"
+#ifdef CONFIG_IPC_DEV
+#include <linux/poll.h>
+#include <linux/devfs_fs_kernel.h>
+#endif
 
 /* sysctl: */
 int msg_ctlmax = MSGMAX;
@@ -79,6 +85,9 @@
        struct list_head q_messages;
        struct list_head q_receivers;
        struct list_head q_senders;
+#ifdef CONFIG_IPC_DEV
+       wait_queue_head_t ipc_dev_wait; /* For the poll methode */
+#endif
 };
 
 #define SEARCH_ANY             1
@@ -112,11 +121,51 @@
 #ifdef CONFIG_PROC_FS
        create_proc_read_entry("sysvipc/msg", 0, 0,
sysvipc_msg_read_proc, NULL);
 #endif
+#ifdef CONFIG_IPC_DEV
+       devfs_mk_dir(NULL, "ipc", NULL);
+#endif
+}
+
+#ifdef CONFIG_IPC_DEV
+static unsigned int ipc_dev_poll(struct file *file, poll_table *wait)
+{
+       int msqid=(int)file->private_data;
+       struct msg_queue *msq;
+       unsigned int ret = 0;
+
+       msq = msg_lock(msqid);
+       if(msq==NULL)
+               return -EINVAL;
+       ret = -EIDRM;
+       if (msg_checkid(msq,msqid))
+               goto out_unlock;
+       ret = -EACCES;
+       if (ipcperms (&msq->q_perm, S_IRUGO))
+               goto out_unlock;
+        
+       poll_wait(file, &msq->ipc_dev_wait, wait);
+
+       ret = 0;
+       if(msq->q_qnum)
+               ret = POLLIN | POLLRDNORM;
+
+out_unlock:
+       msg_unlock(msqid);
+       return ret;
 }
 
+static struct file_operations ipc_dev_fops = {
+       poll:    ipc_dev_poll,
+};
+#endif
+
 static int newque (key_t key, int msgflg)
 {
        int id;
+#ifdef CONFIG_IPC_DEV
+       int msgid;
+       char name[32];
+#endif
        struct msg_queue *msq;
 
        msq  = (struct msg_queue *) kmalloc (sizeof (*msq), GFP_KERNEL);
@@ -138,9 +187,21 @@
        INIT_LIST_HEAD(&msq->q_messages);
        INIT_LIST_HEAD(&msq->q_receivers);
        INIT_LIST_HEAD(&msq->q_senders);
+#ifdef CONFIG_IPC_DEV
+       init_waitqueue_head(&msq->ipc_dev_wait);
+#endif
        msg_unlock(id);
 
+#ifdef CONFIG_IPC_DEV
+       msgid = msg_buildid(id,msq->q_perm.seq);
+       sprintf(name, "ipc/%d", msgid);
+       devfs_register(NULL, name,
+                       DEVFS_FL_DEFAULT, 0, 0, S_IFREG | S_IRUSR,
+                       &ipc_dev_fops, (void*)msgid);
+       return msgid;
+#else
        return msg_buildid(id,msq->q_perm.seq);
+#endif
 }
 
 static void free_msg(struct msg_msg* msg)
@@ -686,6 +747,9 @@
        msq->q_lspid = current->pid;
        msq->q_stime = CURRENT_TIME;
 
+#ifdef CONFIG_IPC_DEV
+       wake_up_interruptible_sync(&msq->ipc_dev_wait);
+#endif
        if(!pipelined_send(msq,msg)) {
                /* noone is waiting for this message, enqueue it */
                list_add_tail(&msg->m_list,&msq->q_messages);

=== send.c ===========================================================

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <sys/msg.h>

#define KEY 1235
#define MSGSZ 200

typedef struct msgbuftoto {
  long mtype;
  char mtext[MSGSZ];
} msgtoto;

int main(int argc, char *argv[])
{
  int ret;
  int msqid;
  msgtoto toto;

  assert((msqid=msgget(KEY, 0664|IPC_CREAT))!=-1);
  printf("msqid=%d\n", msqid);
  toto.mtype=1;
  strncpy(toto.mtext, argv[1], MSGSZ);
  assert((ret=msgsnd(msqid, (struct msgbuf*)&toto, MSGSZ, 0))!=-1);

  return 0;
}

=== poll_receive.c =====================================================

#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/msg.h>
#include <sys/poll.h>
#include <sys/types.h>
#include <sys/stat.h>

#define KEY 1235
#define MSGSZ 200

typedef struct msgbuftoto {
  long mtype;
  char mtext[MSGSZ];
} msgtoto;

int main(int argc, char *argv[])
{
  int ret;
  int msqid;
  char name[32];
  struct pollfd pfd;
  msgtoto toto;

  assert((msqid=msgget(KEY, 0664|IPC_CREAT))!=-1);
  sprintf(name, "/dev/ipc/%d", msqid);
  assert((pfd.fd=open(name, O_RDONLY))!=-1);
  pfd.events=POLLIN;
  printf("poll start...\n");
  assert(poll(&pfd, 1, -1)!=-1);
  printf("poll done!\n");
  assert((ret=msgrcv(msqid, (struct msgbuf*)&toto, MSGSZ, 0, 0))!=-1);
  assert(close(pfd.fd)!=-1);
  printf("%s\n", toto.mtext);

  return 0;
}

===================================================================
--
Jean-Christian de Rivaz 
mailto:jc@lightning.ch

                 reply	other threads:[~2001-12-04  2:51 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3C0BB490.AE523828@lightning.ch \
    --to=jcdr@lightning.ch \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox