void v_serviceNotify( v_service service, v_event event, c_voidp userData) { assert(service != NULL); assert(C_TYPECHECK(service, v_service)); assert(event != NULL); if (event->kind == V_EVENT_NEW_GROUP) { if (event->data && service->newGroups) { ospl_c_insert(service->newGroups, event->data); } } v_participantNotify(v_participant(service), event, userData); }
/************************************************************** * Protected functions **************************************************************/ void v_serviceNotify( v_service service, v_event event, c_voidp userData) { v_group group; assert(service != NULL); assert(C_TYPECHECK(service, v_service)); if (event != NULL) { switch (event->kind) { case V_EVENT_SERVICESTATE_CHANGED: break; case V_EVENT_NEW_GROUP: group = v_group(event->userData); if ((group != NULL) && (v_observer(service)->eventData != NULL)) { /* Update new group admin */ c_insert((c_set)v_observer(service)->eventData, group); } /* This allows receiving the event by means of a waitset.*/ v_observableNotify(v_observable(service), event); break; case V_EVENT_HISTORY_DELETE: /* This allows receiving the event by means of a waitset.*/ v_observableNotify(v_observable(service), event); break; case V_EVENT_HISTORY_REQUEST: /* This allows receiving the event by means of a waitset.*/ v_observableNotify(v_observable(service), event); break; case V_EVENT_CONNECT_WRITER: case V_EVENT_PERSISTENT_SNAPSHOT: /* This allows receiving the event by means of a waitset.*/ v_observableNotify(v_observable(service), event); break; default: break; } } v_participantNotify(v_participant(service), event, userData); }
/** * PRE: v_observerLock has been called. * * When the text 'intentionally no break' is set after a case label * the class specified by the label has not implemented the notify * method. */ void v_observerNotify( v_observer _this, v_event event, c_voidp userData) { /* This Notify method is part of the observer-observable pattern. * It is designed to be invoked when _this object as observer receives * an event from an observable object. * It must be possible to pass the event to the subclass of itself by * calling <subclass>Notify(_this, event, userData). * This implies that _this cannot be locked within any Notify method * to avoid deadlocks. * For consistency _this must be locked by v_observerLock(_this) before * calling this method. */ c_ulong trigger; assert(_this != NULL); assert(C_TYPECHECK(_this,v_observer)); /* The observer will be made insensitive to event as soon as the * observer is deinitialized. However it may be that destruction * of the observer has started before the deinit of the observer * is called. In that case the V_EVENT_OBJECT_DESTROYED flag will * be set to avoid processing of incomming events. */ if ((_this->eventFlags & V_EVENT_OBJECT_DESTROYED) == 0) { /* The observer is valid so the event can be processed. */ if (event != NULL ) { trigger = event->kind & _this->eventMask; } else { /* NULL-event always notifies observers */ trigger = V_EVENT_TRIGGER; } /* The following code invokes the observers subclass specific * notification method. * This is a bit strange that the observer has knowledge about * the subclass notification methods, a better model is that * subclasses register the notification method to the observer * instead. The reason for this model is that registering a * function pointer is only valid in the process scope and this * method will typically be called from another process. */ if (trigger != 0) { switch (v_objectKind(_this)) { case K_DATAREADER: v_dataReaderNotify(v_dataReader(_this), event, userData); break; case K_WAITSET: v_waitsetNotify(v_waitset(_this), event, userData); break; case K_PARTICIPANT: v_participantNotify(v_participant(_this), event, userData); break; case K_TOPIC: v_topicNotify(v_topic(_this), event, userData); break; case K_QUERY: /* v_queryNotify(v_query(_this), event, userData); */ break; case K_SPLICED: /* intentionally no break */ case K_SERVICE: case K_NETWORKING: case K_DURABILITY: case K_CMSOAP: v_serviceNotify(v_service(_this), event, userData); break; case K_SERVICEMANAGER: v_serviceManagerNotify(v_serviceManager(_this), event, userData); break; case K_WRITER: /* no action for the following observers */ case K_PUBLISHER: case K_SUBSCRIBER: case K_GROUPQUEUE: break; default: OS_REPORT_1(OS_INFO,"Kernel Observer",0, "Notify an unknown observer type: %d", v_objectKind(_this)); break; } /* * Only trigger condition variable if at least * one thread is waiting AND the event is seen for the first time. */ if ((_this->waitCount > 0) && ((trigger == V_EVENT_TRIGGER) || (~_this->eventFlags & trigger))) { _this->eventFlags |= trigger; /* store event */ c_condBroadcast(&_this->cv); } else { _this->eventFlags |= trigger; /* store event */ } } } /* else observer object destroyed, skip notification */ }