svn commit: samba r16565 - in branches/tmp/vl-messaging/source/lib: .

ab at samba.org ab at samba.org
Tue Jun 27 15:59:33 GMT 2006


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.



More information about the samba-cvs mailing list