16ba597c5SAnurag S. Maskey /*
26ba597c5SAnurag S. Maskey  * CDDL HEADER START
36ba597c5SAnurag S. Maskey  *
46ba597c5SAnurag S. Maskey  * The contents of this file are subject to the terms of the
56ba597c5SAnurag S. Maskey  * Common Development and Distribution License (the "License").
66ba597c5SAnurag S. Maskey  * You may not use this file except in compliance with the License.
76ba597c5SAnurag S. Maskey  *
86ba597c5SAnurag S. Maskey  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96ba597c5SAnurag S. Maskey  * or http://www.opensolaris.org/os/licensing.
106ba597c5SAnurag S. Maskey  * See the License for the specific language governing permissions
116ba597c5SAnurag S. Maskey  * and limitations under the License.
126ba597c5SAnurag S. Maskey  *
136ba597c5SAnurag S. Maskey  * When distributing Covered Code, include this CDDL HEADER in each
146ba597c5SAnurag S. Maskey  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156ba597c5SAnurag S. Maskey  * If applicable, add the following below this CDDL HEADER, with the
166ba597c5SAnurag S. Maskey  * fields enclosed by brackets "[]" replaced with your own identifying
176ba597c5SAnurag S. Maskey  * information: Portions Copyright [yyyy] [name of copyright owner]
186ba597c5SAnurag S. Maskey  *
196ba597c5SAnurag S. Maskey  * CDDL HEADER END
206ba597c5SAnurag S. Maskey  */
216ba597c5SAnurag S. Maskey 
226ba597c5SAnurag S. Maskey /*
236ba597c5SAnurag S. Maskey  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
246ba597c5SAnurag S. Maskey  * Use is subject to license terms.
256ba597c5SAnurag S. Maskey  */
266ba597c5SAnurag S. Maskey 
276ba597c5SAnurag S. Maskey #include <assert.h>
286ba597c5SAnurag S. Maskey #include <dirent.h>
296ba597c5SAnurag S. Maskey #include <errno.h>
306ba597c5SAnurag S. Maskey #include <fcntl.h>
316ba597c5SAnurag S. Maskey #include <pthread.h>
326ba597c5SAnurag S. Maskey #include <stdio.h>
336ba597c5SAnurag S. Maskey #include <stdlib.h>
346ba597c5SAnurag S. Maskey #include <strings.h>
356ba597c5SAnurag S. Maskey #include <string.h>
366ba597c5SAnurag S. Maskey #include <syslog.h>
376ba597c5SAnurag S. Maskey #include <sys/msg.h>
386ba597c5SAnurag S. Maskey #include <sys/stat.h>
396ba597c5SAnurag S. Maskey #include <sys/types.h>
406ba597c5SAnurag S. Maskey #include <unistd.h>
416ba597c5SAnurag S. Maskey 
426ba597c5SAnurag S. Maskey #include "libnwam_impl.h"
436ba597c5SAnurag S. Maskey #include <libnwam_priv.h>
446ba597c5SAnurag S. Maskey #include <libnwam.h>
456ba597c5SAnurag S. Maskey 
466ba597c5SAnurag S. Maskey /*
476ba597c5SAnurag S. Maskey  * Implementation of event notification mechanism used by the GUI and
486ba597c5SAnurag S. Maskey  * nwamadm.  Clients register for events via nwam_events_init() and
496ba597c5SAnurag S. Maskey  * unregister via nwam_events_fini().  nwamd sends events via nwam_event_send()
506ba597c5SAnurag S. Maskey  * and applications block waiting for a new event to be delivered in
516ba597c5SAnurag S. Maskey  * nwam_event_wait().  Events are implemented as System V message queues,
526ba597c5SAnurag S. Maskey  * one per event client.  The event mechanism has to be resilient to
536ba597c5SAnurag S. Maskey  * nwamd restarts so that clients do not lose the event connection.
546ba597c5SAnurag S. Maskey  */
556ba597c5SAnurag S. Maskey 
566ba597c5SAnurag S. Maskey #define	NWAM_EVENT_MSG_DIR		"/etc/svc/volatile/nwam/"
576ba597c5SAnurag S. Maskey #define	NWAM_EVENT_MSG_FILE		"nwam_event_msgs"
596ba597c5SAnurag S. Maskey #define	NWAM_EVENT_MAX_SIZE		(sizeof (struct nwam_event) + \
60*69b43529SMichael Hunter 	(NWAMD_MAX_NUM_WLANS * sizeof (nwam_wlan_t)))
616ba597c5SAnurag S. Maskey #define	NWAM_EVENT_WAIT_TIME		10
626ba597c5SAnurag S. Maskey #define	NWAM_EVENT_MAX_NUM_PENDING	25
636ba597c5SAnurag S. Maskey 
646ba597c5SAnurag S. Maskey /*
656ba597c5SAnurag S. Maskey  * This is protecting simultaneous access to the msqid and its configuration.
666ba597c5SAnurag S. Maskey  */
676ba597c5SAnurag S. Maskey static pthread_mutex_t event_mutex = PTHREAD_MUTEX_INITIALIZER;
686ba597c5SAnurag S. Maskey static int event_msqid = -1;
696ba597c5SAnurag S. Maskey 
706ba597c5SAnurag S. Maskey static nwam_error_t
nwam_event_alloc(nwam_event_t * eventp)716ba597c5SAnurag S. Maskey nwam_event_alloc(nwam_event_t *eventp)
726ba597c5SAnurag S. Maskey {
736ba597c5SAnurag S. Maskey 	assert(eventp != NULL);
746ba597c5SAnurag S. Maskey 
756ba597c5SAnurag S. Maskey 	*eventp = calloc(1, NWAM_EVENT_MAX_SIZE);
766ba597c5SAnurag S. Maskey 	if (*eventp == NULL)
776ba597c5SAnurag S. Maskey 		return (NWAM_NO_MEMORY);
786ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
796ba597c5SAnurag S. Maskey }
806ba597c5SAnurag S. Maskey 
816ba597c5SAnurag S. Maskey void
nwam_event_free(nwam_event_t event)826ba597c5SAnurag S. Maskey nwam_event_free(nwam_event_t event)
836ba597c5SAnurag S. Maskey {
846ba597c5SAnurag S. Maskey 	if (event != NULL)
856ba597c5SAnurag S. Maskey 		free(event);
866ba597c5SAnurag S. Maskey }
876ba597c5SAnurag S. Maskey 
886ba597c5SAnurag S. Maskey /*
896ba597c5SAnurag S. Maskey  * Get next event in queue.
906ba597c5SAnurag S. Maskey  */
916ba597c5SAnurag S. Maskey nwam_error_t
nwam_event_wait(nwam_event_t * eventp)926ba597c5SAnurag S. Maskey nwam_event_wait(nwam_event_t *eventp)
936ba597c5SAnurag S. Maskey {
946ba597c5SAnurag S. Maskey 	nwam_error_t err;
956ba597c5SAnurag S. Maskey 	nwam_event_t event;
966ba597c5SAnurag S. Maskey 
976ba597c5SAnurag S. Maskey 	assert(eventp != NULL);
986ba597c5SAnurag S. Maskey 
996ba597c5SAnurag S. Maskey 	if ((err = nwam_event_alloc(&event)) != NWAM_SUCCESS)
1006ba597c5SAnurag S. Maskey 		return (err);
1016ba597c5SAnurag S. Maskey 	while (msgrcv(event_msqid, (struct msgbuf *)event, NWAM_EVENT_MAX_SIZE,
1026ba597c5SAnurag S. Maskey 	    0, 0) == -1) {
1036ba597c5SAnurag S. Maskey 		switch (errno) {
1046ba597c5SAnurag S. Maskey 			case EAGAIN:
1056ba597c5SAnurag S. Maskey 			case EBUSY:
1066ba597c5SAnurag S. Maskey 				/*
1076ba597c5SAnurag S. Maskey 				 * We see this errno eventhough it isn't
1086ba597c5SAnurag S. Maskey 				 * documented.  Try again.  If this causes
1096ba597c5SAnurag S. Maskey 				 * a busy loop then grab a trace otherwise
1106ba597c5SAnurag S. Maskey 				 * it's a brace 'til we can figure out why it
1116ba597c5SAnurag S. Maskey 				 * happens.
1126ba597c5SAnurag S. Maskey 				 */
1136ba597c5SAnurag S. Maskey 				continue;
1146ba597c5SAnurag S. Maskey 
1156ba597c5SAnurag S. Maskey 			default:
1166ba597c5SAnurag S. Maskey 				nwam_event_free(event);
1176ba597c5SAnurag S. Maskey 				return (nwam_errno_to_nwam_error(errno));
1186ba597c5SAnurag S. Maskey 		}
1196ba597c5SAnurag S. Maskey 	}
1206ba597c5SAnurag S. Maskey 
1216ba597c5SAnurag S. Maskey 	/* Resize event down from maximum size */
1226ba597c5SAnurag S. Maskey 	if ((*eventp = realloc(event, event->nwe_size)) == NULL)
1236ba597c5SAnurag S. Maskey 		return (NWAM_NO_MEMORY);
1246ba597c5SAnurag S. Maskey 
1256ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
1266ba597c5SAnurag S. Maskey }
1276ba597c5SAnurag S. Maskey 
1286ba597c5SAnurag S. Maskey /*
1296ba597c5SAnurag S. Maskey  * Register for receipt of events from nwamd.  Event delivery is
1306ba597c5SAnurag S. Maskey  * done via a System V message queue.
1316ba597c5SAnurag S. Maskey  */
1326ba597c5SAnurag S. Maskey nwam_error_t
nwam_events_init(void)1336ba597c5SAnurag S. Maskey nwam_events_init(void)
1346ba597c5SAnurag S. Maskey {
1356ba597c5SAnurag S. Maskey 	char eventmsgfile[MAXPATHLEN];
1366ba597c5SAnurag S. Maskey 	nwam_error_t err;
1376ba597c5SAnurag S. Maskey 	nwam_error_t rc = NWAM_SUCCESS;
1386ba597c5SAnurag S. Maskey 	key_t key;
1396ba597c5SAnurag S. Maskey 
1406ba597c5SAnurag S. Maskey 	(void) snprintf(eventmsgfile, sizeof (eventmsgfile), "%s.%d",
1416ba597c5SAnurag S. Maskey 	    NWAM_EVENT_MSG_FILE_PREFIX, getpid());
1426ba597c5SAnurag S. Maskey 
1436ba597c5SAnurag S. Maskey 	(void) pthread_mutex_lock(&event_mutex);
1446ba597c5SAnurag S. Maskey 
1456ba597c5SAnurag S. Maskey 	if (event_msqid != -1) {
1466ba597c5SAnurag S. Maskey 		rc = NWAM_ENTITY_IN_USE;
1476ba597c5SAnurag S. Maskey 		goto exit;
1486ba597c5SAnurag S. Maskey 	}
1496ba597c5SAnurag S. Maskey 
1506ba597c5SAnurag S. Maskey 	if ((err = nwam_request_register_unregister
1516ba597c5SAnurag S. Maskey 	    (NWAM_REQUEST_TYPE_EVENT_REGISTER, eventmsgfile)) != NWAM_SUCCESS) {
1526ba597c5SAnurag S. Maskey 		rc = err;
1536ba597c5SAnurag S. Maskey 		goto exit;
1546ba597c5SAnurag S. Maskey 	}
1556ba597c5SAnurag S. Maskey 
1566ba597c5SAnurag S. Maskey 	if ((key = ftok(eventmsgfile, 0)) == -1) {
1576ba597c5SAnurag S. Maskey 		rc = nwam_errno_to_nwam_error(errno);
1586ba597c5SAnurag S. Maskey 		goto exit;
1596ba597c5SAnurag S. Maskey 	}
1606ba597c5SAnurag S. Maskey 
1616ba597c5SAnurag S. Maskey 	/* Get system-wide message queue ID */
1626ba597c5SAnurag S. Maskey 	if ((event_msqid = msgget(key, 0444)) == -1) {
1636ba597c5SAnurag S. Maskey 		rc = nwam_errno_to_nwam_error(errno);
1646ba597c5SAnurag S. Maskey 		goto exit;
1656ba597c5SAnurag S. Maskey 	}
1666ba597c5SAnurag S. Maskey 
1676ba597c5SAnurag S. Maskey exit:
1686ba597c5SAnurag S. Maskey 	(void) pthread_mutex_unlock(&event_mutex);
1696ba597c5SAnurag S. Maskey 
1706ba597c5SAnurag S. Maskey 	return (rc);
1716ba597c5SAnurag S. Maskey }
1726ba597c5SAnurag S. Maskey 
1736ba597c5SAnurag S. Maskey /*
1746ba597c5SAnurag S. Maskey  * Un-register for receipt of events from nwamd.  Make a request to nwamd
1756ba597c5SAnurag S. Maskey  * to destroy the message queue.
1766ba597c5SAnurag S. Maskey  */
1776ba597c5SAnurag S. Maskey void
nwam_events_fini(void)1786ba597c5SAnurag S. Maskey nwam_events_fini(void)
1796ba597c5SAnurag S. Maskey {
1806ba597c5SAnurag S. Maskey 	char eventmsgfile[MAXPATHLEN];
1816ba597c5SAnurag S. Maskey 
1826ba597c5SAnurag S. Maskey 	(void) snprintf(eventmsgfile, sizeof (eventmsgfile), "%s.%d",
1836ba597c5SAnurag S. Maskey 	    NWAM_EVENT_MSG_FILE_PREFIX, getpid());
1846ba597c5SAnurag S. Maskey 
1856ba597c5SAnurag S. Maskey 	(void) pthread_mutex_lock(&event_mutex);
1866ba597c5SAnurag S. Maskey 
1876ba597c5SAnurag S. Maskey 	(void) nwam_request_register_unregister
1886ba597c5SAnurag S. Maskey 	    (NWAM_REQUEST_TYPE_EVENT_UNREGISTER, eventmsgfile);
1896ba597c5SAnurag S. Maskey 
1906ba597c5SAnurag S. Maskey 	event_msqid = -1;
1916ba597c5SAnurag S. Maskey 
1926ba597c5SAnurag S. Maskey 	(void) pthread_mutex_unlock(&event_mutex);
1936ba597c5SAnurag S. Maskey }
1946ba597c5SAnurag S. Maskey 
1956ba597c5SAnurag S. Maskey /*
1966ba597c5SAnurag S. Maskey  * Create an event queue.  Called by nwamd to create System V message queues
1976ba597c5SAnurag S. Maskey  * for clients to listen for events.
1986ba597c5SAnurag S. Maskey  */
1996ba597c5SAnurag S. Maskey nwam_error_t
nwam_event_queue_init(const char * eventmsgfile)2006ba597c5SAnurag S. Maskey nwam_event_queue_init(const char *eventmsgfile)
2016ba597c5SAnurag S. Maskey {
2026ba597c5SAnurag S. Maskey 	int fd;
2036ba597c5SAnurag S. Maskey 	key_t key;
2046ba597c5SAnurag S. Maskey 
2056ba597c5SAnurag S. Maskey 	if ((fd = open(eventmsgfile, O_RDWR | O_CREAT | O_TRUNC, 0644)) == -1)
2066ba597c5SAnurag S. Maskey 		return (nwam_errno_to_nwam_error(errno));
2076ba597c5SAnurag S. Maskey 	(void) close(fd);
2086ba597c5SAnurag S. Maskey 
2096ba597c5SAnurag S. Maskey 	if ((key = ftok(eventmsgfile, 0)) == -1)
2106ba597c5SAnurag S. Maskey 		return (nwam_errno_to_nwam_error(errno));
2116ba597c5SAnurag S. Maskey 
2126ba597c5SAnurag S. Maskey 	if (msgget(key, 0644 | IPC_CREAT) == -1)
2136ba597c5SAnurag S. Maskey 		return (nwam_errno_to_nwam_error(errno));
2146ba597c5SAnurag S. Maskey 
2156ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
2166ba597c5SAnurag S. Maskey }
2176ba597c5SAnurag S. Maskey 
2186ba597c5SAnurag S. Maskey /*
2196ba597c5SAnurag S. Maskey  * Send event to registered listeners via the set of registered System V
2206ba597c5SAnurag S. Maskey  * message queues.
2216ba597c5SAnurag S. Maskey  */
2226ba597c5SAnurag S. Maskey nwam_error_t
nwam_event_send(nwam_event_t event)2236ba597c5SAnurag S. Maskey nwam_event_send(nwam_event_t event)
2246ba597c5SAnurag S. Maskey {
2256ba597c5SAnurag S. Maskey 	DIR *dirp;
2266ba597c5SAnurag S. Maskey 	struct dirent *dp;
2276ba597c5SAnurag S. Maskey 	struct msqid_ds buf;
2286ba597c5SAnurag S. Maskey 	key_t key;
2296ba597c5SAnurag S. Maskey 	int msqid;
2306ba597c5SAnurag S. Maskey 	char eventmsgfile[MAXPATHLEN];
2316ba597c5SAnurag S. Maskey 	nwam_error_t err = NWAM_SUCCESS;
2326ba597c5SAnurag S. Maskey 
2336ba597c5SAnurag S. Maskey 	if ((dirp = opendir(NWAM_EVENT_MSG_DIR)) == NULL) {
2346ba597c5SAnurag S. Maskey 		return (nwam_errno_to_nwam_error(errno));
2356ba597c5SAnurag S. Maskey 	}
2366ba597c5SAnurag S. Maskey 
2376ba597c5SAnurag S. Maskey 	/*
2386ba597c5SAnurag S. Maskey 	 * For each file matching our event message queue file prefix,
2396ba597c5SAnurag S. Maskey 	 * check the queue is still being read, and if so send the message.
2406ba597c5SAnurag S. Maskey 	 */
2416ba597c5SAnurag S. Maskey 	while ((dp = readdir(dirp)) != NULL) {
2426ba597c5SAnurag S. Maskey 		if (strncmp(dp->d_name, NWAM_EVENT_MSG_FILE,
2436ba597c5SAnurag S. Maskey 		    strlen(NWAM_EVENT_MSG_FILE)) != 0)
2446ba597c5SAnurag S. Maskey 			continue;
2456ba597c5SAnurag S. Maskey 
2466ba597c5SAnurag S. Maskey 		(void) snprintf(eventmsgfile, sizeof (eventmsgfile), "%s/%s",
2476ba597c5SAnurag S. Maskey 		    NWAM_EVENT_MSG_DIR, dp->d_name);
2486ba597c5SAnurag S. Maskey 
2496ba597c5SAnurag S. Maskey 		if ((key = ftok(eventmsgfile, 0)) == -1) {
2506ba597c5SAnurag S. Maskey 			int errno_save = errno;
2516ba597c5SAnurag S. Maskey 			syslog(LOG_INFO, "nwam_event_send: ftok: %s",
2526ba597c5SAnurag S. Maskey 			    strerror(errno_save));
2536ba597c5SAnurag S. Maskey 			err = nwam_errno_to_nwam_error(errno_save);
2546ba597c5SAnurag S. Maskey 			continue;
2556ba597c5SAnurag S. Maskey 		}
2566ba597c5SAnurag S. Maskey 
2576ba597c5SAnurag S. Maskey 		if ((msqid = msgget(key, 0644)) == -1) {
2586ba597c5SAnurag S. Maskey 			int errno_save = errno;
2596ba597c5SAnurag S. Maskey 			syslog(LOG_INFO, "nwam_event_send: msgget: %s",
2606ba597c5SAnurag S. Maskey 			    strerror(errno_save));
2616ba597c5SAnurag S. Maskey 			err = nwam_errno_to_nwam_error(errno_save);
2626ba597c5SAnurag S. Maskey 			continue;
2636ba597c5SAnurag S. Maskey 		}
2646ba597c5SAnurag S. Maskey 
2656ba597c5SAnurag S. Maskey 		/* Retrieve stats to analyse queue activity */
2666ba597c5SAnurag S. Maskey 		if (msgctl(msqid, IPC_STAT, &buf) == -1) {
2676ba597c5SAnurag S. Maskey 			int errno_save = errno;
2686ba597c5SAnurag S. Maskey 			syslog(LOG_INFO, "nwam_event_send: msgctl: %s",
2696ba597c5SAnurag S. Maskey 			    strerror(errno_save));
2706ba597c5SAnurag S. Maskey 			err = nwam_errno_to_nwam_error(errno_save);
2716ba597c5SAnurag S. Maskey 			continue;
2726ba597c5SAnurag S. Maskey 		}
2736ba597c5SAnurag S. Maskey 		/*
2746ba597c5SAnurag S. Maskey 		 * If buf.msg_qnum > NWAM_EVENT_MAX_NUM_PENDING
2756ba597c5SAnurag S. Maskey 		 * _and_ msg_stime is more than 10s after msg_rtime -
2766ba597c5SAnurag S. Maskey 		 * indicating message(s) have been hanging around unclaimed -
2776ba597c5SAnurag S. Maskey 		 * we destroy the queue as the client has most likely gone
2786ba597c5SAnurag S. Maskey 		 * away. This can happen if a registered client hits Ctrl^C.
2796ba597c5SAnurag S. Maskey 		 */
2806ba597c5SAnurag S. Maskey 		if (buf.msg_qnum > NWAM_EVENT_MAX_NUM_PENDING &&
2816ba597c5SAnurag S. Maskey 		    ((buf.msg_stime + NWAM_EVENT_WAIT_TIME) > buf.msg_rtime)) {
2826ba597c5SAnurag S. Maskey 			nwam_event_queue_fini(eventmsgfile);
2836ba597c5SAnurag S. Maskey 			continue;
2846ba597c5SAnurag S. Maskey 		}
2856ba597c5SAnurag S. Maskey 
2866ba597c5SAnurag S. Maskey 		/*
2876ba597c5SAnurag S. Maskey 		 * This shouldn't ever block.  If it does then log an error and
2886ba597c5SAnurag S. Maskey 		 * clean up the queue.
2896ba597c5SAnurag S. Maskey 		 */
2906ba597c5SAnurag S. Maskey 		if (msgsnd(msqid, (struct msgbuf *)event, event->nwe_size,
2916ba597c5SAnurag S. Maskey 		    IPC_NOWAIT) == -1) {
2926ba597c5SAnurag S. Maskey 			int errno_save = errno;
2936ba597c5SAnurag S. Maskey 			syslog(LOG_ERR, "nwam_event_send: msgsnd: %s, "
2946ba597c5SAnurag S. Maskey 			    "destroying message queue %s", strerror(errno_save),
2956ba597c5SAnurag S. Maskey 			    eventmsgfile);
2966ba597c5SAnurag S. Maskey 			nwam_event_queue_fini(eventmsgfile);
2976ba597c5SAnurag S. Maskey 			err = nwam_errno_to_nwam_error(errno_save);
2986ba597c5SAnurag S. Maskey 			continue;
2996ba597c5SAnurag S. Maskey 		}
3006ba597c5SAnurag S. Maskey 
3016ba597c5SAnurag S. Maskey 	}
3026ba597c5SAnurag S. Maskey 	(void) closedir(dirp);
3036ba597c5SAnurag S. Maskey 
3046ba597c5SAnurag S. Maskey 	return (err);
3056ba597c5SAnurag S. Maskey }
3066ba597c5SAnurag S. Maskey 
3076ba597c5SAnurag S. Maskey /*
3086ba597c5SAnurag S. Maskey  * Destroy an event queue.  Called by nwamd to destroy the associated message
3096ba597c5SAnurag S. Maskey  * queue.
3106ba597c5SAnurag S. Maskey  */
3116ba597c5SAnurag S. Maskey void
nwam_event_queue_fini(const char * eventmsgfile)3126ba597c5SAnurag S. Maskey nwam_event_queue_fini(const char *eventmsgfile)
3136ba597c5SAnurag S. Maskey {
3146ba597c5SAnurag S. Maskey 	key_t key;
3156ba597c5SAnurag S. Maskey 	int msqid;
3166ba597c5SAnurag S. Maskey 
3176ba597c5SAnurag S. Maskey 	if ((key = ftok(eventmsgfile, 0)) != -1 &&
3186ba597c5SAnurag S. Maskey 	    (msqid = msgget(key, 0644)) != -1 &&
3196ba597c5SAnurag S. Maskey 	    msgctl(msqid, IPC_RMID, NULL) != -1)
3206ba597c5SAnurag S. Maskey 		(void) unlink(eventmsgfile);
3216ba597c5SAnurag S. Maskey }
3226ba597c5SAnurag S. Maskey 
3236ba597c5SAnurag S. Maskey /*
3246ba597c5SAnurag S. Maskey  * Stop sending events.  Called by nwamd to destroy each System V message queue
3256ba597c5SAnurag S. Maskey  * registered.