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.