Author: ab
Date: 2006-06-27 15:59:33 +0000 (Tue, 27 Jun 2006)
New Revision: 16565

WebSVN: 
http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=16565

Log:
Extending messaging API to allow dispatching messages with the specified
 message type mask. It's necessary for the lockd part.
Modified:
   branches/tmp/vl-messaging/source/lib/messages.c
   branches/tmp/vl-messaging/source/lib/messages_socket.c
   branches/tmp/vl-messaging/source/lib/messages_tdb.c


Changeset:
Modified: branches/tmp/vl-messaging/source/lib/messages.c
===================================================================
--- branches/tmp/vl-messaging/source/lib/messages.c     2006-06-27 15:14:56 UTC 
(rev 16564)
+++ branches/tmp/vl-messaging/source/lib/messages.c     2006-06-27 15:59:33 UTC 
(rev 16565)
@@ -59,6 +59,8 @@
                                         fd_set *rfds, fd_set *wfds);
 static unsigned int (*message_receive_func)(fd_set *rfds, fd_set *wfds);
 static BOOL (*retrieve_all_messages_func)(struct message_list **list);
+static BOOL (*retrieve_mask_messages_func)(unsigned int mask,
+                                                                               
   struct message_list **list);
 
 /* we have a linked list of dispatch handlers */
 static struct dispatch_fns {
@@ -110,6 +112,7 @@
                message_select_setup_func = NULL;
                message_receive_func = NULL;
                retrieve_all_messages_func = retrieve_all_messages_tdb;
+               retrieve_mask_messages_func = retrieve_mask_messages_tdb;
                if(!message_init_tdb()) return False;
                break;
        case MESSAGING_TYPE_DGRAM:
@@ -119,6 +122,7 @@
                message_select_setup_func = message_select_setup_socket;
                message_receive_func = message_receive_socket;
                retrieve_all_messages_func = retrieve_all_messages_socket;
+               retrieve_mask_messages_func = retrieve_mask_messages_socket;
                if(!message_init_socket()) return False;
                break;
        default:
@@ -169,7 +173,9 @@
 
        message_send_pid_func = NULL;
        message_select_setup_func = NULL;
+       message_receive_func = NULL;
        retrieve_all_messages_func = NULL;
+       retrieve_mask_messages_func = NULL;
 
        return True;
 }
@@ -241,6 +247,17 @@
 }
 
 /****************************************************************************
+ Retrieve all messages for the current process with the specified types mask.
+****************************************************************************/
+
+static BOOL retrieve_mask_messages(unsigned int mask,
+                                                                  struct 
message_list **list)
+{
+       SMB_ASSERT(retrieve_mask_messages_func != NULL);
+       return retrieve_mask_messages_func(mask, list);
+}
+
+/****************************************************************************
  Set selectors for messaging sockets
 ****************************************************************************/
 
@@ -266,6 +283,84 @@
 }
 
 /****************************************************************************
+ Converts message type to message type mask
+****************************************************************************/
+
+BOOL message_type_mask(unsigned int msg_type, unsigned int *msg_mask)
+{
+       BOOL result = True;
+
+       if (msg_type < 1000)
+               *msg_mask = FLAG_MSG_GENERAL;
+       else if (msg_type > 1000 && msg_type < 2000)
+               *msg_mask = FLAG_MSG_NMBD;
+       else if (msg_type > 2000 && msg_type < 2100)
+               *msg_mask = FLAG_MSG_PRINT_NOTIFY;
+       else if (msg_type > 2100 && msg_type < 3000)
+               *msg_mask = FLAG_MSG_PRINT_GENERAL;
+       else if (msg_type > 3000 && msg_type < 4000)
+               *msg_mask = FLAG_MSG_SMBD;
+       else {
+               result = False;
+       }
+
+       return result;
+}
+
+/****************************************************************************
+ Receive and dispatch any messages pending for this process with the
+ specified types mask
+****************************************************************************/
+
+void message_dispatch_mask(unsigned int mask)
+{
+       struct message_list *list = NULL, *p;
+       struct dispatch_fns *dfn;
+       int n_handled;
+
+       if (!retrieve_mask_messages(mask, &list))
+               return ;
+
+       DEBUG(10,("A couple of messages received\n"));
+
+       for (p = list; p; p = p->next) {
+               struct message_rec* msg = p->msg;               
+               DEBUG(10,("message_dispatch: received msg_type=%d "
+                         "src_pid=%u\n", msg->msg_type,
+                         (unsigned int) procid_to_pid(&msg->src)));
+               n_handled = 0;
+               for (dfn = dispatch_fns; dfn; dfn = dfn->next) {
+                       if (dfn->msg_type != msg->msg_type) {
+                               continue;
+                       }
+                       DEBUG(10,("message_dispatch: processing message "
+                                 "of type %d.\n", msg->msg_type));
+                       if(msg->len == sizeof(struct message_rec)) {
+                               dfn->fn(msg->msg_type, msg->src, NULL, 0);
+                       } else {
+                               dfn->fn(msg->msg_type, msg->src, 
+                                       (void *)((uint8_t*)msg +
+                                                sizeof(struct message_rec)),
+                                       msg->len - sizeof(struct message_rec));
+                       }
+                       n_handled++;
+               }
+               if (!n_handled) {
+                       DEBUG(5,("message_dispatch: warning: no handlers "
+                                "registed for msg_type %d in pid %u\n",
+                               msg-> msg_type, (unsigned int)sys_getpid()));
+               }
+       }
+       
+       /* free the list of received messages */
+       while(list) {
+               struct message_list *next = list->next;
+               TALLOC_FREE(list);
+               list = next;
+       }       
+}
+
+/****************************************************************************
  Receive and dispatch any messages pending for this process.
  Notice that all dispatch handlers for a particular msg_type get called,
  so you can register multiple handlers for a message.
@@ -350,6 +445,34 @@
 }
 
 /****************************************************************************
+ Wait for messages (of the specified mask) with timeout and dispatch them
+****************************************************************************/
+
+void message_select_and_dispatch_mask(unsigned int mask, struct timeval *tv)
+{
+       fd_set rfds, wfds;
+       int maxfd = 0, selres;
+               
+       FD_ZERO(&rfds);
+       FD_ZERO(&wfds);
+       
+       message_select_setup(&maxfd, &rfds, &wfds);
+       
+       selres = sys_select(maxfd+1, &rfds, &wfds, NULL, tv);
+       if(selres < 0 && errno != EINTR) {
+               DEBUG(2, ("select failed: %s\n", strerror(errno)));
+       }
+       if(selres > 0) {
+               if(message_receive(&rfds, &wfds) != selres) {
+                       DEBUG(2, ("message dispatching error\n"));
+                       return;
+               }
+       }       
+
+       message_dispatch_mask(mask);
+}
+
+/****************************************************************************
  Register a dispatch function for a particular message type.
  *NOTE*: Dispatch functions must be able to cope with incoming
  messages on an *odd* byte boundary.
@@ -469,18 +592,9 @@
        struct msg_all msg_all;
 
        msg_all.msg_type = msg_type;
-       if (msg_type < 1000)
-               msg_all.msg_flag = FLAG_MSG_GENERAL;
-       else if (msg_type > 1000 && msg_type < 2000)
-               msg_all.msg_flag = FLAG_MSG_NMBD;
-       else if (msg_type > 2000 && msg_type < 2100)
-               msg_all.msg_flag = FLAG_MSG_PRINT_NOTIFY;
-       else if (msg_type > 2100 && msg_type < 3000)
-               msg_all.msg_flag = FLAG_MSG_PRINT_GENERAL;
-       else if (msg_type > 3000 && msg_type < 4000)
-               msg_all.msg_flag = FLAG_MSG_SMBD;
-       else
+       if(!message_type_mask(msg_all.msg_type, &msg_all.msg_flag)) {
                return False;
+       }
 
        msg_all.buf = buf;
        msg_all.len = len;

Modified: branches/tmp/vl-messaging/source/lib/messages_socket.c
===================================================================
--- branches/tmp/vl-messaging/source/lib/messages_socket.c      2006-06-27 
15:14:56 UTC (rev 16564)
+++ branches/tmp/vl-messaging/source/lib/messages_socket.c      2006-06-27 
15:59:33 UTC (rev 16565)
@@ -242,6 +242,32 @@
 }
 
 /****************************************************************************
+ Retrieve all messages for the current process with the specified types mask.
+****************************************************************************/
+
+BOOL retrieve_mask_messages_socket(unsigned int mask,
+                                                                  struct 
message_list **list)
+{
+       if(received_messages != NULL) {
+               struct message_list *li = received_messages, *tmp;
+
+               while(li) {
+                       unsigned int mm = 0;
+                       if(message_type_mask(li->msg->msg_type, &mm) && (mm & 
mask)) {
+                               struct message_list *next = li->next;
+                               DLIST_REMOVE(received_messages, li);
+                               DLIST_ADD_END((*list), li, tmp);
+                               li = next;
+                       }
+                       li = li->next;
+               }
+               return (*list != NULL);
+       } else {
+               return False;
+       }
+}
+
+/****************************************************************************
  Set selectors for messaging sockets
 ****************************************************************************/
 

Modified: branches/tmp/vl-messaging/source/lib/messages_tdb.c
===================================================================
--- branches/tmp/vl-messaging/source/lib/messages_tdb.c 2006-06-27 15:14:56 UTC 
(rev 16564)
+++ branches/tmp/vl-messaging/source/lib/messages_tdb.c 2006-06-27 15:59:33 UTC 
(rev 16565)
@@ -364,6 +364,17 @@
        return True;
 }
 
+/****************************************************************************
+ Retrieve all messages for the current process with the specified types mask.
+****************************************************************************/
+
+BOOL retrieve_mask_messages_tdb(unsigned int mask,
+                                                               struct 
message_list **list)
+{
+       /* TODO */
+       return False;
+}
+
 /*
  * Block and unblock receiving of messages. Allows removal of race conditions
  * when doing a fork and changing message disposition.

Reply via email to