4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
39 #include "conditions.h"
45 * events.c - contains routines which create/destroy event sources,
46 * handle the event queue and process events from that queue.
49 /* Add new event sources here. */
50 struct nwamd_event_source
{
52 void (*events_init
)(void);
53 void (*events_fini
)(void);
56 nwamd_routing_events_init
, nwamd_routing_events_fini
},
58 nwamd_sysevent_events_init
, nwamd_sysevent_events_fini
},
61 /* Counter for event ids */
62 static uint64_t event_id_counter
= 0;
64 static uu_list_pool_t
*event_pool
= NULL
;
65 static uu_list_t
*event_queue
= NULL
;
66 static pthread_mutex_t event_queue_mutex
= PTHREAD_MUTEX_INITIALIZER
;
67 static pthread_cond_t event_queue_cond
= PTHREAD_COND_INITIALIZER
;
69 static int nwamd_event_compare(const void *, const void *, void *);
72 nwamd_event_name(int event_type
)
74 if (event_type
<= NWAM_EVENT_MAX
)
75 return (nwam_event_type_to_string(event_type
));
78 case NWAM_EVENT_TYPE_OBJECT_INIT
:
79 return ("OBJECT_INIT");
80 case NWAM_EVENT_TYPE_OBJECT_FINI
:
81 return ("OBJECT_FINI");
82 case NWAM_EVENT_TYPE_TIMED_CHECK_CONDITIONS
:
83 return ("TIMED_CHECK_CONDITIONS");
84 case NWAM_EVENT_TYPE_TRIGGERED_CHECK_CONDITIONS
:
85 return ("TRIGGERED_CHECK_CONDITIONS");
86 case NWAM_EVENT_TYPE_NCU_CHECK
:
88 case NWAM_EVENT_TYPE_TIMER
:
90 case NWAM_EVENT_TYPE_UPGRADE
:
92 case NWAM_EVENT_TYPE_PERIODIC_SCAN
:
93 return ("PERIODIC_SCAN");
94 case NWAM_EVENT_TYPE_QUEUE_QUIET
:
95 return ("QUEUE_QUIET");
102 nwamd_event_sources_init(void)
107 * Now we can safely initialize event sources.
110 i
< sizeof (event_sources
) / sizeof (struct nwamd_event_source
);
112 if (event_sources
[i
].events_init
!= NULL
)
113 event_sources
[i
].events_init();
118 nwamd_event_sources_fini(void)
123 i
< sizeof (event_sources
) / sizeof (struct nwamd_event_source
);
125 if (event_sources
[i
].events_init
!= NULL
)
126 event_sources
[i
].events_fini();
131 * Comparison function for events, passed in as callback to
132 * uu_list_pool_create(). Compare by time, so that timer
133 * event queue can be sorted by nearest time to present.
137 nwamd_event_compare(const void *l_arg
, const void *r_arg
, void *private)
139 nwamd_event_t l
= (nwamd_event_t
)l_arg
;
140 nwamd_event_t r
= (nwamd_event_t
)r_arg
;
143 rv
= l
->event_time
.tv_sec
- r
->event_time
.tv_sec
;
145 rv
= l
->event_time
.tv_nsec
- r
->event_time
.tv_nsec
;
151 nwamd_event_queue_init(void)
153 event_pool
= uu_list_pool_create("event_queue_pool",
154 sizeof (struct nwamd_event
),
155 offsetof(struct nwamd_event
, event_node
),
156 nwamd_event_compare
, UU_LIST_POOL_DEBUG
);
157 if (event_pool
== NULL
)
158 pfail("uu_list_pool_create failed with error %d", uu_error());
159 event_queue
= uu_list_create(event_pool
, NULL
, UU_LIST_SORTED
);
160 if (event_queue
== NULL
)
161 pfail("uu_list_create failed with error %d", uu_error());
165 nwamd_event_queue_fini(void)
170 while ((event
= uu_list_teardown(event_queue
, &cookie
)) != NULL
)
171 nwamd_event_fini(event
);
172 uu_list_destroy(event_queue
);
173 if (event_pool
!= NULL
)
174 uu_list_pool_destroy(event_pool
);
178 nwamd_event_init(int32_t type
, nwam_object_type_t object_type
,
179 size_t size
, const char *object_name
)
183 event
= calloc(1, sizeof (struct nwamd_event
));
185 nlog(LOG_ERR
, "nwamd_event_init: could not create %s event for "
186 "object %s", nwamd_event_name(type
),
187 object_name
!= NULL
? object_name
: "<no object>");
191 /* Is this an externally-visible event? */
192 if (type
<= NWAM_EVENT_MAX
) {
193 event
->event_send
= B_TRUE
;
194 event
->event_msg
= calloc(1, sizeof (struct nwam_event
) + size
);
195 if (event
->event_msg
== NULL
) {
197 "nwamd_event_init: could not create %s event",
198 nwamd_event_name(type
));
202 event
->event_msg
->nwe_type
= type
;
203 event
->event_msg
->nwe_size
= sizeof (struct nwam_event
) + size
;
205 event
->event_send
= B_FALSE
;
206 event
->event_msg
= NULL
;
209 event
->event_type
= type
;
211 if (object_name
!= NULL
) {
212 (void) strlcpy(event
->event_object
, object_name
,
214 event
->event_object_type
= object_type
;
216 event
->event_object
[0] = '\0';
220 event
->event_id
= atomic_add_64_nv(&event_id_counter
, 1);
221 (void) clock_gettime(CLOCK_REALTIME
, &event
->event_time
);
227 nwamd_event_do_not_send(nwamd_event_t event
)
229 nlog(LOG_DEBUG
, "nwamd_event_do_not_send: cancelling delivery of "
230 "event %s for object %s", nwamd_event_name(event
->event_type
),
231 event
->event_object
[0] != '\0' ?
232 event
->event_object
: "<no object>");
233 event
->event_send
= B_FALSE
;
237 nwamd_event_fini(nwamd_event_t event
)
240 free(event
->event_msg
);
246 nwamd_event_init_object_action(nwam_object_type_t object_type
,
247 const char *object_name
, const char *parent_name
,
248 nwam_action_t object_action
)
252 event
= nwamd_event_init(NWAM_EVENT_TYPE_OBJECT_ACTION
,
253 object_type
, 0, object_name
);
257 event
->event_msg
->nwe_data
.nwe_object_action
.nwe_action
= object_action
;
258 event
->event_msg
->nwe_data
.nwe_object_action
.nwe_object_type
=
260 (void) strlcpy(event
->event_msg
->nwe_data
.nwe_object_action
.nwe_name
,
262 sizeof (event
->event_msg
->nwe_data
.nwe_object_action
.nwe_name
));
263 if (parent_name
== NULL
) {
264 event
->event_msg
->nwe_data
.nwe_object_action
.nwe_parent
[0] =
269 (event
->event_msg
->nwe_data
.nwe_object_action
.nwe_parent
,
271 sizeof (event
->event_msg
->nwe_data
.nwe_object_action
.nwe_parent
));
276 nwamd_event_init_object_state(nwam_object_type_t object_type
,
277 const char *object_name
, nwam_state_t state
, nwam_aux_state_t aux_state
)
281 event
= nwamd_event_init(NWAM_EVENT_TYPE_OBJECT_STATE
,
282 object_type
, 0, object_name
);
286 event
->event_msg
->nwe_data
.nwe_object_state
.nwe_state
= state
;
287 event
->event_msg
->nwe_data
.nwe_object_state
.nwe_aux_state
= aux_state
;
288 event
->event_msg
->nwe_data
.nwe_object_state
.nwe_object_type
=
290 (void) strlcpy(event
->event_msg
->nwe_data
.nwe_object_state
.nwe_name
,
292 sizeof (event
->event_msg
->nwe_data
.nwe_object_state
.nwe_name
));
298 nwamd_event_init_priority_group_change(int64_t priority
)
302 event
= nwamd_event_init(NWAM_EVENT_TYPE_PRIORITY_GROUP
,
303 NWAM_OBJECT_TYPE_UNKNOWN
, 0, NULL
);
307 event
->event_msg
->nwe_data
.nwe_priority_group_info
.nwe_priority
=
314 nwamd_event_init_link_action(const char *name
, nwam_action_t link_action
)
320 if ((err
= nwam_ncu_name_to_typed_name(name
, NWAM_NCU_TYPE_LINK
,
321 &object_name
)) != NWAM_SUCCESS
) {
322 nlog(LOG_ERR
, "nwamd_event_init_link_action: "
323 "nwam_ncu_name_to_typed_name: %s",
327 event
= nwamd_event_init(NWAM_EVENT_TYPE_LINK_ACTION
,
328 NWAM_OBJECT_TYPE_NCU
, 0, object_name
);
333 (void) strlcpy(event
->event_msg
->nwe_data
.nwe_link_action
.nwe_name
,
335 sizeof (event
->event_msg
->nwe_data
.nwe_link_action
.nwe_name
));
336 event
->event_msg
->nwe_data
.nwe_link_action
.nwe_action
= link_action
;
342 nwamd_event_init_link_state(const char *name
, boolean_t up
)
348 if ((err
= nwam_ncu_name_to_typed_name(name
, NWAM_NCU_TYPE_LINK
,
349 &object_name
)) != NWAM_SUCCESS
) {
350 nlog(LOG_ERR
, "nwamd_event_init_link_state: "
351 "nwam_ncu_name_to_typed_name: %s",
356 event
= nwamd_event_init(NWAM_EVENT_TYPE_LINK_STATE
,
357 NWAM_OBJECT_TYPE_NCU
, 0, object_name
);
362 (void) strlcpy(event
->event_msg
->nwe_data
.nwe_link_state
.nwe_name
, name
,
363 sizeof (event
->event_msg
->nwe_data
.nwe_link_state
.nwe_name
));
364 event
->event_msg
->nwe_data
.nwe_link_state
.nwe_link_up
= up
;
370 nwamd_event_init_if_state(const char *linkname
, uint32_t flags
,
371 uint32_t addr_added
, struct sockaddr
*addr
, struct sockaddr
*netmask
)
377 /* linkname does not contain the lifnum */
378 if ((err
= nwam_ncu_name_to_typed_name(linkname
,
379 NWAM_NCU_TYPE_INTERFACE
, &object_name
)) != NWAM_SUCCESS
) {
380 nlog(LOG_ERR
, "nwamd_event_init_if_state: "
381 "nwam_ncu_name_to_typed_name: %s",
386 event
= nwamd_event_init(NWAM_EVENT_TYPE_IF_STATE
,
387 NWAM_OBJECT_TYPE_NCU
, 0, object_name
);
392 (void) strlcpy(event
->event_msg
->nwe_data
.nwe_if_state
.nwe_name
,
394 sizeof (event
->event_msg
->nwe_data
.nwe_if_state
.nwe_name
));
395 event
->event_msg
->nwe_data
.nwe_if_state
.nwe_flags
= flags
;
396 event
->event_msg
->nwe_data
.nwe_if_state
.nwe_addr_added
= addr_added
;
397 event
->event_msg
->nwe_data
.nwe_if_state
.nwe_addr_valid
= (addr
!= NULL
);
400 bcopy(addr
, &(event
->event_msg
->nwe_data
.nwe_if_state
.nwe_addr
),
401 addr
->sa_family
== AF_INET
? sizeof (struct sockaddr_in
) :
402 sizeof (struct sockaddr_in6
));
404 if (netmask
!= NULL
) {
406 &(event
->event_msg
->nwe_data
.nwe_if_state
.nwe_netmask
),
407 netmask
->sa_family
== AF_INET
?
408 sizeof (struct sockaddr_in
) : sizeof (struct sockaddr_in6
));
415 nwamd_event_init_wlan(const char *name
, int32_t type
, boolean_t connected
,
416 nwam_wlan_t
*wlans
, uint_t num_wlans
)
424 case NWAM_EVENT_TYPE_WLAN_SCAN_REPORT
:
425 case NWAM_EVENT_TYPE_WLAN_NEED_CHOICE
:
426 size
= sizeof (nwam_wlan_t
) * (num_wlans
- 1);
428 case NWAM_EVENT_TYPE_WLAN_NEED_KEY
:
429 case NWAM_EVENT_TYPE_WLAN_CONNECTION_REPORT
:
432 nlog(LOG_ERR
, "nwamd_event_init_wlan: unexpected "
433 "event type %s (%d)", nwamd_event_name(type
), type
);
436 if ((err
= nwam_ncu_name_to_typed_name(name
, NWAM_NCU_TYPE_LINK
,
437 &object_name
)) != NWAM_SUCCESS
) {
438 nlog(LOG_ERR
, "nwamd_event_init_wlan: "
439 "nwam_ncu_name_to_typed_name: %s",
444 event
= nwamd_event_init(type
, NWAM_OBJECT_TYPE_NCU
, size
, object_name
);
449 (void) strlcpy(event
->event_msg
->nwe_data
.nwe_wlan_info
.nwe_name
, name
,
450 sizeof (event
->event_msg
->nwe_data
.nwe_wlan_info
.nwe_name
));
451 event
->event_msg
->nwe_data
.nwe_wlan_info
.nwe_connected
= connected
;
452 event
->event_msg
->nwe_data
.nwe_wlan_info
.nwe_num_wlans
= num_wlans
;
455 (void) memcpy(event
->event_msg
->nwe_data
.nwe_wlan_info
.nwe_wlans
, wlans
,
456 num_wlans
* sizeof (nwam_wlan_t
));
462 nwamd_event_init_ncu_check(void)
464 return (nwamd_event_init(NWAM_EVENT_TYPE_NCU_CHECK
,
465 NWAM_OBJECT_TYPE_NCP
, 0, NULL
));
469 nwamd_event_init_init(void)
471 return (nwamd_event_init(NWAM_EVENT_TYPE_INIT
,
472 NWAM_OBJECT_TYPE_UNKNOWN
, 0, NULL
));
476 nwamd_event_init_shutdown(void)
478 return (nwamd_event_init(NWAM_EVENT_TYPE_SHUTDOWN
,
479 NWAM_OBJECT_TYPE_UNKNOWN
, 0, NULL
));
483 * Add event to the event list.
486 nwamd_event_enqueue(nwamd_event_t event
)
488 nwamd_event_enqueue_timed(event
, 0);
492 * Schedule an event to be added to the event list for future processing.
493 * The event will be scheduled in delta_seconds seconds mod schedule delay and
497 nwamd_event_enqueue_timed(nwamd_event_t event
, int delta_seconds
)
501 nlog(LOG_DEBUG
, "enqueueing event %lld %d (%s) for object %s in %ds",
502 event
->event_id
, event
->event_type
,
503 nwamd_event_name(event
->event_type
),
504 event
->event_object
[0] != 0 ? event
->event_object
: "none",
507 (void) clock_gettime(CLOCK_REALTIME
, &event
->event_time
);
508 event
->event_time
.tv_sec
+= delta_seconds
;
510 uu_list_node_init(event
, &event
->event_node
, event_pool
);
512 (void) pthread_mutex_lock(&event_queue_mutex
);
515 * Find appropriate location to insert the event based on time.
517 (void) uu_list_find(event_queue
, event
, NULL
, &idx
);
518 (void) uu_list_insert(event_queue
, event
, idx
);
520 (void) pthread_cond_signal(&event_queue_cond
);
521 (void) pthread_mutex_unlock(&event_queue_mutex
);
525 * Is the specified event enqueued on the event (or pending event queue)
526 * for execution in when seconds? An object may be specified also.
529 nwamd_event_enqueued(int32_t event_type
, nwam_object_type_t object_type
,
534 (void) pthread_mutex_lock(&event_queue_mutex
);
535 for (event
= uu_list_first(event_queue
);
537 event
= uu_list_next(event_queue
, event
)) {
538 if (event
->event_type
!= event_type
)
540 if (object_type
!= NWAM_OBJECT_TYPE_UNKNOWN
&&
541 event
->event_object_type
!= object_type
)
543 if (object
!= NULL
&& strcmp(object
, event
->event_object
) != 0)
545 (void) pthread_mutex_unlock(&event_queue_mutex
);
548 (void) pthread_mutex_unlock(&event_queue_mutex
);
554 * Is the time in the past.
557 in_past(struct timespec t
)
561 (void) clock_gettime(CLOCK_REALTIME
, &now
);
562 if (t
.tv_sec
< now
.tv_sec
)
564 if (t
.tv_sec
> now
.tv_sec
)
566 if (t
.tv_nsec
< now
.tv_nsec
)
572 * Remove event at head of event list for processing. This takes a number of
573 * nanoseconds to wait. If the number is 0 then it blocks. If there is
574 * nothing on the queue then it returns an event which says that the queue
578 nwamd_event_dequeue(long nsec
)
582 (void) pthread_mutex_lock(&event_queue_mutex
);
583 event
= uu_list_first(event_queue
);
584 if (event
== NULL
&& nsec
== 0) {
586 (void) pthread_cond_wait(&event_queue_cond
,
588 } while ((event
= uu_list_first(event_queue
)) == NULL
);
590 struct timespec waitcap
;
593 (void) clock_gettime(CLOCK_REALTIME
, &waitcap
);
594 waitcap
.tv_nsec
+= nsec
;
595 waitcap
.tv_sec
+= NSEC_TO_SEC(waitcap
.tv_nsec
);
596 waitcap
.tv_nsec
= NSEC_TO_FRACNSEC(waitcap
.tv_nsec
);
600 * Keep going as long as the first event hasn't matured and
601 * we havn't passed our maximum wait time.
603 while ((event
== NULL
|| !in_past(event
->event_time
)) &&
604 (nsec
== 0 || !in_past(waitcap
))) {
605 struct timespec eventwait
;
609 * no maximum waittime - just use the event
610 * both an event and cap - take the least one
611 * just a maximum waittime - use it
614 eventwait
= event
->event_time
;
615 } else if (event
!= NULL
) {
617 diff
= SEC_TO_NSEC(event
->event_time
.tv_sec
-
619 event
->event_time
.tv_nsec
- waitcap
.tv_nsec
;
624 eventwait
= event
->event_time
;
627 * Note that if the event is NULL then nsec is
628 * nonzero and waitcap is valid.
633 (void) pthread_cond_timedwait(&event_queue_cond
,
634 &event_queue_mutex
, &eventwait
);
635 event
= uu_list_first(event_queue
);
640 * At this point we've met the guard contition of the while loop.
641 * The event at the top of the queue might be mature in which case
642 * we use it. Otherwise we hit our cap and we need to enqueue a
643 * quiesced queue event.
645 if (event
!= NULL
&& in_past(event
->event_time
)) {
646 uu_list_remove(event_queue
, event
);
647 uu_list_node_fini(event
, &event
->event_node
, event_pool
);
649 event
= nwamd_event_init(NWAM_EVENT_TYPE_QUEUE_QUIET
,
650 NWAM_OBJECT_TYPE_UNKNOWN
, 0, NULL
);
655 "dequeueing event %lld of type %d (%s) for object %s",
656 event
->event_id
, event
->event_type
,
657 nwamd_event_name(event
->event_type
),
658 event
->event_object
[0] != 0 ? event
->event_object
:
661 (void) pthread_mutex_unlock(&event_queue_mutex
);
667 nwamd_event_send(nwam_event_t event_msg
)
671 if (shutting_down
&& event_msg
->nwe_type
!= NWAM_EVENT_TYPE_SHUTDOWN
) {
672 nlog(LOG_DEBUG
, "nwamd_event_send: tossing event as nwamd "
677 err
= nwam_event_send(event_msg
);
679 if (err
!= NWAM_SUCCESS
) {
680 nlog(LOG_ERR
, "nwamd_event_send: nwam_event_send: %s",
686 * Run state machine for object. Method is run if
687 * - event method is non-null
688 * - event method is valid for current object state (determined by
689 * ORing the current state against the set of valid states for the method).
691 * If these criteria are met, the method is run.
694 nwamd_event_run_method(nwamd_event_t event
)
696 nwamd_event_method_t
*event_methods
;
699 event_methods
= nwamd_object_event_methods(event
->event_object_type
);
701 /* If we're shutting down, only fini events are accepted for objects */
702 if (shutting_down
&& event
->event_type
!= NWAM_EVENT_TYPE_OBJECT_FINI
) {
703 nlog(LOG_DEBUG
, "nwamd_event_run_method: tossing non-fini "
704 "event %s for object %s",
705 nwamd_event_name(event
->event_type
), event
->event_object
);
710 event_methods
[i
].event_type
!= NWAM_EVENT_TYPE_NOOP
;
712 if (event_methods
[i
].event_type
==
714 event_methods
[i
].event_method
!= NULL
) {
716 "(%p) %s: running method for event %s",
717 (void *)event
, event
->event_object
,
718 nwamd_event_name(event
->event_type
));
720 event_methods
[i
].event_method(event
);
724 nlog(LOG_DEBUG
, "(%p) %s: no matching method for event %d (%s)",
725 (void *)event
, event
->event_object
, event
->event_type
,
726 nwamd_event_name(event
->event_type
));
730 * Called when we are checking to see what should be activated. First activate
731 * all of the manual NCUs. Then see if we can find a valid priority group.
732 * If we can, activate it. Otherwise try all the priority groups starting
733 * with the lowest one that makes sense.
736 nwamd_activate_ncus(void) {
737 int64_t prio
= INVALID_PRIORITY_GROUP
;
740 nwamd_ncp_activate_manual_ncus();
741 selected
= nwamd_ncp_check_priority_group(&prio
);
744 * Activate chosen priority group and stop anything going on in
745 * lesser priority groups.
747 nwamd_ncp_activate_priority_group(prio
);
748 nwamd_ncp_deactivate_priority_group_all(prio
+ 1);
751 * Nothing unique could be started so try them all. Once one
752 * of them gets into a reasonable state then we will prune
753 * everything below it (see first part of this conditional).
755 int64_t oldprio
= INVALID_PRIORITY_GROUP
;
756 while (nwamd_ncp_find_next_priority_group(++oldprio
, &prio
)) {
757 nwamd_ncp_activate_priority_group(prio
);
764 * Event handler thread
766 * The complexity in this code comes about from wanting to delay the decision
767 * making process until after bursts of events. Keep roughly polling (waiting
768 * for .1s) until we see the queue quiet event and then block.
771 nwamd_event_handler(void)
773 boolean_t got_shutdown_event
= B_FALSE
;
774 boolean_t check_conditions
= B_FALSE
;
775 boolean_t ncu_check
= B_FALSE
;
776 int queue_quiet_time
= 0;
780 * Dequeue events and process them. In most cases, events have
781 * an assocated object type, and we use this to retrieve
782 * the function that will process the event.
784 while (!got_shutdown_event
) {
785 event
= nwamd_event_dequeue(queue_quiet_time
);
786 /* keep pulling events as long as they are close together */
787 queue_quiet_time
= SEC_TO_NSEC(1)/10;
790 * This is an event with no associated object.
792 if (event
->event_object
[0] == '\0') {
793 switch (event
->event_type
) {
794 case NWAM_EVENT_TYPE_NOOP
:
795 case NWAM_EVENT_TYPE_INIT
:
797 * The only action for an INIT event
798 * is to relay it to event listeners,
799 * which is done below.
802 case NWAM_EVENT_TYPE_PRIORITY_GROUP
:
803 (void) pthread_mutex_lock(&active_ncp_mutex
);
804 current_ncu_priority_group
=
805 event
->event_msg
->nwe_data
.
806 nwe_priority_group_info
.nwe_priority
;
807 (void) pthread_mutex_unlock(&active_ncp_mutex
);
809 case NWAM_EVENT_TYPE_TIMED_CHECK_CONDITIONS
:
810 if (!shutting_down
) {
811 nwamd_set_timed_check_all_conditions();
812 check_conditions
= B_TRUE
;
815 case NWAM_EVENT_TYPE_TRIGGERED_CHECK_CONDITIONS
:
817 check_conditions
= B_TRUE
;
819 case NWAM_EVENT_TYPE_NCU_CHECK
:
823 case NWAM_EVENT_TYPE_UPGRADE
:
824 if (!shutting_down
) {
826 * Upgrade events have no associated
829 nwamd_event_run_method(event
);
832 case NWAM_EVENT_TYPE_SHUTDOWN
:
833 got_shutdown_event
= B_TRUE
;
837 * We want to delay processing of condition and ncu
838 * checking until after short bursts of events. So we
839 * keep track of times we've scheduled checking and
840 * wait for the queue to quiesce.
842 case NWAM_EVENT_TYPE_QUEUE_QUIET
:
843 queue_quiet_time
= 0; /* now we can block */
844 if (!shutting_down
&& check_conditions
) {
845 nwamd_check_all_conditions();
846 check_conditions
= B_FALSE
;
849 if (!shutting_down
&& ncu_check
) {
850 nwamd_activate_ncus();
857 "event %d (%s)had no object associated "
858 "with it", event
->event_type
,
859 nwamd_event_name(event
->event_type
));
864 * Event has an associated object - run event method
865 * for that object type (if any).
867 nwamd_event_run_method(event
);
870 * Send associated message to listeners if event type is
871 * externally visible.
873 if (event
->event_send
)
874 nwamd_event_send(event
->event_msg
);
876 nwamd_event_fini(event
);
878 /* If we get here, we got a shutdown event. */
879 nwamd_event_queue_fini();
880 nwamd_object_lists_fini();