/// <summary> /// This operation detaches a Condition from the WaitSet. If the Condition was not attached /// to this WaitSet, the operation returns PreconditionNotMet /// </summary> /// <param name="condition">The attached condition in the WaitSet which is to be detached.</param> /// <returns>Possible return codes are: Ok, Error, BadParameter, OutOfResources or PreconditionNotMet.</returns> public ReturnCode DetachCondition(ICondition condition) { ReturnCode result = DDS.ReturnCode.BadParameter; Condition condImpl = condition as Condition; ReportStack.Start(); if (condImpl == null) { ReportStack.Report(result, "cond is invalid (null), or not of type " + "DDS::OpenSplice::Condition"); } else { lock (this) { result = condImpl.DetachFromWaitSet(this); // ALREADY_DELETED may only apply to the WaitSet in this context, // so for a deleted condition use BAD_PARAMETER instead. if (result == DDS.ReturnCode.AlreadyDeleted) { result = DDS.ReturnCode.BadParameter; } } } ReportStack.Flush(this, result != ReturnCode.Ok); return(result); }
internal override ReturnCode DetachFromWaitSet(WaitSet waitset) { ReturnCode result = DDS.ReturnCode.AlreadyDeleted; ReportStack.Start(); lock (this) { if (this.rlReq_isAlive) { if (waitSetList.Remove(waitset)) { result = waitset.wlReq_DetachGuardCondition(this); } else { result = DDS.ReturnCode.PreconditionNotMet; } } } // if (result != DDS.ReturnCode.Ok) { // OS_REPORT(OS_ERROR, // "Condition::detach_waitset", 0, // "detach failed with %s", // DDS::OpenSplice::Utils::returnCodeToString(result)); // } return(result); }
internal override ReturnCode AttachToWaitSet(WaitSet waitset) { ReturnCode result = DDS.ReturnCode.AlreadyDeleted; ReportStack.Start(); lock (this) { if (this.rlReq_isAlive) { if (!waitSetList.Contains(waitset)) { result = waitset.wlReq_AttachGuardCondition(this); if (result == DDS.ReturnCode.Ok) { /* The waitset will detach itself when it is destructed. */ waitSetList.Add(waitset); } } else { result = DDS.ReturnCode.Ok; } } } return(result); }
internal override ReturnCode AttachToWaitSet(WaitSet waitset) { ReturnCode result = DDS.ReturnCode.AlreadyDeleted; ReportStack.Start(); lock (this) { if (this.rlReq_isAlive) { if (!waitSetList.Contains(waitset)) { result = waitset.wlReq_AttachGuardCondition(this); if (result == DDS.ReturnCode.Ok) { /* The waitset will detach itself when it is destructed. */ waitSetList.Add(waitset); } } else { result = DDS.ReturnCode.Ok; } } } // if (result != DDS.ReturnCode.Ok) { // OS_REPORT(OS_ERROR, // "Condition::attach_waitset", 0, // "attach failed with %s", // DDS::OpenSplice::Utils::returnCodeToString(result)); // } return(result); }
/// <summary> /// This operation gets the default DomainParticipantQos of the DomainParticipantFactory /// </summary> /// <remarks> /// This operation gets the default DomainParticipantQos of the /// DomainParticipantFactory (that is the struct with the QosPolicy settings) /// which is used for newly created IDomainParticipant objects, in case no QoS is used /// in the CreateParticipant operation. /// /// The application must provide the DomainParticipantQos struct in which the /// QosPolicy settings can be stored and provide a reference to the struct. The /// operation writes the default QosPolicy settings to the struct referenced to by qos.<br> /// Any settings in the struct are overwritten.<br> /// The values retrieved by this operation match the set of values specified on the last /// successful call to SetDefaultParticipantQos(), or, if the call was never /// made, the default values as specified for each QosPolicy setting. /// </remarks> /// @param qos A reference to the DomainParticipantQos in which the default /// DomainParticipantQos for the IDomainParticipant is written /// @return DDS.ReturnCode Ok - The new default DomainParticipantQos is set /// @return DDS.ReturnCode Error - An internal error has occured /// @return DDS.ReturnCode OutOfResources - The DDS ran out of resources to complete this operation public ReturnCode GetDefaultParticipantQos(ref DomainParticipantQos qos) { ReturnCode result; using (OpenSplice.CustomMarshalers.DomainParticipantQosMarshaler marshaler = new OpenSplice.CustomMarshalers.DomainParticipantQosMarshaler()) { lock (singleton_lock) { ReportStack.Start(); result = marshaler.CopyIn(defaultParticipantQos); if (result == ReturnCode.Ok) { marshaler.CopyOut(ref qos); // Listener scheduling qospolicy is not part of User Layer, so obtain it separately from participant. if (qos.ListenerScheduling.SchedulingClass == null) { qos.ListenerScheduling.SchedulingClass = new SchedulingClassQosPolicy(); } qos.ListenerScheduling.SchedulingClass.Kind = this.defaultParticipantQos.ListenerScheduling.SchedulingClass.Kind; if (qos.ListenerScheduling.SchedulingPriorityKind == null) { qos.ListenerScheduling.SchedulingPriorityKind = new SchedulingPriorityQosPolicy(); } qos.ListenerScheduling.SchedulingPriorityKind.Kind = this.defaultParticipantQos.ListenerScheduling.SchedulingPriorityKind.Kind; qos.ListenerScheduling.SchedulingPriority = this.defaultParticipantQos.ListenerScheduling.SchedulingPriority; } ReportStack.Flush(null, result != ReturnCode.Ok); } } return(result); }
/// <summary> /// This operation creates a new IDomainParticipant which will join the domain /// identified by domainId, with the desired DomainParticipantQos and attaches /// the specified IDomainParticipantListener to it and uses the given communication /// StatusKind mask. /// </summary> /// <remarks> /// <i><b>Identifying the Domain</b></i><br> /// The IDomainParticipant will attach to the Domain that is specified by the /// domainId parameter. This parameter consists of an integer specified in the Id tag /// in the configuration file. Note that to make multiple connections to a Domain (create /// multiple Participants for the same Domain) within a single process, all of the /// Participants must use the same identification (i.e. all use the same domain Id). /// /// The constant DDS.DomainId.Default can be used for this parameter. If this is done /// the value of Id tag from the configuration file specified by the environment variable /// called OSPL_URI will be used. /// /// It is recommended to use this domain Id in conjunction with the OSPL_URI /// environment variable instead of hard-coding a domain Id into your application, /// since this gives you much more flexibility in the deployment phase of your product.<br> /// See also Section 1.3.2.1, The OSPL_URI environment variable, in the Deployment /// Guide. /// /// <i><b>Communication Status</b></i><br> /// For each communication status, the StatusChangedFlag flag is initially set to /// false. It becomes true whenever that communication status changes. For each /// communication status activated in the mask , the associated /// IDomainParticipantListener operation is invoked and the communication /// status is reset to false , as the listener implicitly accesses the status which is passed /// as a parameter to that operation. The fact that the status is reset prior to calling the /// listener means that if the application calls the Get<status_name>Status from /// inside the listener it will see the status already reset. /// /// The following statuses are applicable to the IDomainParticipant /// - DDS.StatusKind InconsistentTopic (propagated) /// - DDS.StatusKind OfferedDeadlineMissed (propagated) /// - DDS.StatusKind RequestedDeadlineMissed (propagated) /// - DDS.StatusKind OfferedIncompatibleQos (propagated) /// - DDS.StatusKind RequestedIncompatibleQos (propagated) /// - DDS.StatusKind SampleLost (propagated) /// - DDS.StatusKind SampleRejected (propagated) /// - DDS.StatusKind DataOnReaders (propagated) /// - DDS.StatusKind DataAvailable (propagated) /// - DDS.StatusKind LivelinessLost (propagated) /// - DDS.StatusKind LivelinessChanged (propagated) /// - DDS.StatusKind PublicationMatched (propagated) /// - DDS.StatusKind SubscriptionMatched (propagated) /// /// Be aware that the PublicationMatched and SubscriptionMatched /// statuses are not applicable when the infrastructure does not have the /// information available to determine connectivity. This is the case when OpenSplice /// is configured not to maintain discovery information in the Networking Service. (See /// the description for the NetworkingService/Discovery/enabled property in /// the Deployment Manual for more information about this subject.) In this case the /// operation will return NULL. /// /// Status bits are declared as a constant and can be used by the application in an OR /// operation to create a tailored mask. The special constant 0 can /// be used to indicate that the created entity should not respond to any of its available /// statuses. The DDS will therefore attempt to propagate these statuses to its factory. /// /// <i><b>Status Propagation</b></i><br> /// The Data Distribution Service will trigger the most specific and relevant Listener.<br> /// In other words, in case a communication status is also activated on the Listener of /// a contained entity, the Listener on that contained entity is invoked instead of the /// IDomainParticipantListener. This means that a status change on a contained /// entity only invokes the IDomainParticipantListener if the contained entity /// itself does not handle the trigger event generated by the status change. /// /// The statuses DataOnReaders and DataAvailable are /// “Read Communication Statuses” and are an exception to all other plain /// communication statuses: they have no corresponding status structure that can be /// obtained with a Get<status_name>Status operation and they are mutually /// exclusive. When new information becomes available to a IDataReader, the Data /// Distribution Service will first look in an attached and activated /// ISubscriberListener or IDomainParticipantListener (in that order) for the /// DataOnReaders. In case the DataOnReaders can not be /// handled, the Data Distribution Service will look in an attached and activated /// IDataReaderListener, ISubscriberListener or IDomainParticipantListener for /// the DataAvailable (in that order). /// </remarks> /// @param domainId The ID of the Domain to which the IDomainParticipant is joined. /// This should be the ID as specified in the configuration file. /// @param qos a DomainParticipantQos for the new IDomainParticipant. When /// this set of QosPolicy settings is inconsistent, no /// IDomainParticipant is created. /// @param listener A IDomainParticipantListener instance which will be attached to /// the new IDomainParticipant. It is permitted to use null as the /// value of the listener: this behaves as a IDomainParticipantListener /// whose operations perform no action. /// @param mask A bit-mask in which each bit enables the invocation of the /// IDomainParticipantListener for a certain status. /// @return The newly created IDomainParticipant. In case of an error a null is returned. public IDomainParticipant CreateParticipant( DomainId domainId, DomainParticipantQos qos, IDomainParticipantListener listener, StatusKind mask) { DomainParticipant participant = null; ReturnCode result; ReportStack.Start(); result = QosManager.checkQos(qos); if (result == DDS.ReturnCode.Ok) { if (domainId != DDS.DomainId.Invalid) { lock (singleton_lock) { participant = new OpenSplice.DomainParticipant(); result = participant.init(domainId, qos); if (result == ReturnCode.Ok) { result = participant.SetListener(listener, mask); } else { participant = null; } if (result == ReturnCode.Ok) { participantList.Add(participant); if (myQos.EntityFactory.AutoenableCreatedEntities) { result = participant.Enable(); } } } } else { ReportStack.Report(DDS.ReturnCode.BadParameter, "DomainParticipant is using an invalid domain identifier (" + domainId + ")."); } } if (result != ReturnCode.Ok && participant != null) { // Ignore result because we prefer the original error. DeleteParticipant(participant); participant = null; } ReportStack.Flush(null, result != ReturnCode.Ok); return(participant); }
public override bool GetTriggerValue() { bool tValue = false; bool isAlive; ReportStack.Start(); lock (this) { isAlive = this.rlReq_isAlive; if (isAlive) { tValue = triggerValue; } } ReportStack.Flush(this, !isAlive); return(tValue); }
// Attribute containing the delegates to the individual Listener functions. /// <summary> /// This operation returns the reference to the singleton DomainParticipantFactory. /// </summary> /// <remarks> /// The operation is idempotent, that is, it can be called multiple times without /// side-effects and it returns the same DomainParticipantFactory instance. /// /// The operation is static and must be called upon its class. /// <code> /// DDS.DomainParticipantFactory factory = null; /// factory = DomainParticipantFactory.GetInstance(); /// </code> /// </remarks> /// @return DomainParticipantFactory singleton private static DomainParticipantFactory GetInstance() { // GetInstance() is called very infrequently so a simple locked singleton // approach is used. lock (singleton_lock) { if (singletonSelf == null) // If singleton doesn't exist, create it. { if (DDS.OpenSplice.User.u.userInitialise() == V_RESULT.OK) { ReportStack.Start(); singletonSelf = new DomainParticipantFactory(); ReportStack.Flush(null, singletonSelf == null); if (singletonSelf != null) { AppDomain.CurrentDomain.ProcessExit += new EventHandler(ProcessExit); } } } return(singletonSelf); } }
/// <summary> /// This operation deletes an IDomainParticipant. /// </summary> /// <remarks> /// An IDomainParticipant cannot /// be deleted when it has any attached Entity objects. When the operation is called /// on a IDomainParticipant with existing Entity objects, the operation returns /// DDS.ReturnCode PreconditionNotMet. /// </remarks> /// @param a_participant The IDomainParticipant that is to be deleted. /// @return DDS.ReturnCode Ok - The IDomainParticipant is deleted /// @return DDS.ReturnCode Error - An internal error has occurred /// @return DDS.ReturnCode BadParameter - The given IDomainParticipant is not valid /// @return DDS.ReturnCode OutOfResources - The Data Distribution Service ran out of /// resources to complete this operation. /// @return DDS.ReturnCode PreconditionNotMet - The IDomainParticipant contains one /// or more Entity objects. public ReturnCode DeleteParticipant(IDomainParticipant a_participant) { ReturnCode result = DDS.ReturnCode.Ok; ReportStack.Start(); DomainParticipant participant = a_participant as DomainParticipant; if (participant != null) { lock (singleton_lock) { if (participantList.Remove(participant)) { result = participant.wlReq_deinit(); if (result != DDS.ReturnCode.Ok) { participantList.Add(participant); } } else { /* Since there is only one DomainParticipantFactory, the participant * has to be created by this one. If we can't find it anymore, it * must have beel deleted already. */ result = DDS.ReturnCode.BadParameter; ReportStack.Report(result, "DomainParticipant was already deleted."); } } } else { result = ReturnCode.BadParameter; ReportStack.Report(result, "Participant parameter 'a_participant' is null."); } ReportStack.Flush(null, result != DDS.ReturnCode.Ok); return(result); }
GetSubscriberQos( ref SubscriberQos subscriberQos, string id) { ReportStack.Start(); NamedSubscriberQos sQos = new NamedSubscriberQos(); GCHandle qosHandle = GCHandle.Alloc(sQos, GCHandleType.Normal); ReturnCode result = qpResultToReturnCode( OpenSplice.Common.QosProvider.GetSubscriberQos(cmnQpPtr, id, GCHandle.ToIntPtr(qosHandle))); if (result == ReturnCode.Ok) { subscriberQos = sQos.SubscriberQos; } else { ReportStack.Report(result, "Could not copy subscriberQos."); } qosHandle.Free(); ReportStack.Flush(null, result != ReturnCode.Ok); return(result); }
GetParticipantQos( ref DomainParticipantQos participantQos, string id) { ReportStack.Start(); NamedDomainParticipantQos pQos = new NamedDomainParticipantQos(); GCHandle qosHandle = GCHandle.Alloc(pQos, GCHandleType.Normal); ReturnCode result = qpResultToReturnCode( OpenSplice.Common.QosProvider.GetParticipantQos(cmnQpPtr, id, GCHandle.ToIntPtr(qosHandle))); if (result == ReturnCode.Ok) { participantQos = pQos.DomainparticipantQos; } else { ReportStack.Report(result, "Could not copy DomainParticipantQos."); } qosHandle.Free(); ReportStack.Flush(null, result != ReturnCode.Ok); return(result); }
internal override ReturnCode DetachFromWaitSet(WaitSet waitset) { ReturnCode result = DDS.ReturnCode.AlreadyDeleted; ReportStack.Start(); lock (this) { if (this.rlReq_isAlive) { if (waitSetList.Remove(waitset)) { result = waitset.wlReq_DetachGuardCondition(this); } else { result = DDS.ReturnCode.PreconditionNotMet; } } } return(result); }
GetDataWriterQos( ref DataWriterQos datawriterQos, string id) { ReportStack.Start(); NamedDataWriterQos dwQos = new NamedDataWriterQos(); GCHandle qosHandle = GCHandle.Alloc(dwQos, GCHandleType.Normal); ReturnCode result = qpResultToReturnCode( OpenSplice.Common.QosProvider.GetDataWriterQos(cmnQpPtr, id, GCHandle.ToIntPtr(qosHandle))); if (result == ReturnCode.Ok) { datawriterQos = dwQos.DatawriterQos; } else { ReportStack.Report(result, "Could not copy datawriterQos."); } qosHandle.Free(); ReportStack.Flush(null, result != ReturnCode.Ok); return(result); }
public ReturnCode SetTriggerValue(bool value) { WaitSet[] list = null; IntPtr context = IntPtr.Zero; ReturnCode result = DDS.ReturnCode.AlreadyDeleted; ReportStack.Start(); lock (this) { if (this.rlReq_isAlive) { triggerValue = value; context = rlReq_HandleSelf; /* A copy of the list of waitsets is made to be triggered after * the condition is released. Triggering a Waitset will lock the * Waitset whereas the Waitset may lock the condition to get the * trigger value. So If the Condition is locked when triggering * a Waitset a deadlock may occur if the Waitset simultaneously * tries to get the conditions trigger value, by first taking a * copy of all waitsets and then releasing the condition before * triggering the Waitsets this situation is avoided. */ list = waitSetList.ToArray(); result = DDS.ReturnCode.Ok; } } if (result == DDS.ReturnCode.Ok) { foreach (WaitSet ws in list) { ws.trigger(context); } } ReportStack.Flush(this, result != ReturnCode.Ok); return(result); }
/// <summary> /// This operation sets the default DomainParticipantQos of the DomainParticipantFactory. /// </summary> /// <remarks> /// This operation sets the default DomainParticipantQos of the DomainParticipantFactory /// (that is the struct with the QosPolicy settings) which is used for newly created /// IDomainParticipant objects, in case no QoS was provided in the CreateParticipant operation. /// /// The DomainParticipantQos is always self consistent, because its policies do not /// depend on each other. <br> /// This means this operation never returns the ReturnCode InconsistentPolicy. /// /// The values set by this operation are returned by GetDefaultParticipantQos(). /// </remarks> /// @param qos The DomainParticipantQos which contains the new default /// DomainParticipantQos for the newly created DomainParticipants /// @return DDS.ReturnCode Ok - The new default DomainParticipantQos is set /// @return DDS.ReturnCode Error - An internal error has occured /// @return DDS.ReturnCode OutOfResources - The DDS ran out of resources to complete this operation public ReturnCode SetDefaultParticipantQos(DomainParticipantQos qos) { ReturnCode result; lock (singleton_lock) { ReportStack.Start(); result = QosManager.checkQos(qos); if (result == DDS.ReturnCode.Ok) { using (OpenSplice.CustomMarshalers.DomainParticipantQosMarshaler marshaler = new OpenSplice.CustomMarshalers.DomainParticipantQosMarshaler()) { result = marshaler.CopyIn(qos); if (result == ReturnCode.Ok) { marshaler.CopyOut(ref defaultParticipantQos); // Listener scheduling qospolicy is not part of User Layer, so obtain it separately from participant. if (qos.ListenerScheduling.SchedulingClass == null) { return(ReturnCode.BadParameter); } this.defaultParticipantQos.ListenerScheduling.SchedulingClass.Kind = qos.ListenerScheduling.SchedulingClass.Kind; if (qos.ListenerScheduling.SchedulingPriorityKind == null) { return(ReturnCode.BadParameter); } this.defaultParticipantQos.ListenerScheduling.SchedulingPriorityKind.Kind = qos.ListenerScheduling.SchedulingPriorityKind.Kind; this.defaultParticipantQos.ListenerScheduling.SchedulingPriority = qos.ListenerScheduling.SchedulingPriority; } } } ReportStack.Flush(null, result != ReturnCode.Ok); } return(result); }
/// <summary> /// This operation allows an application thread to wait for the occurrence of at least one /// of the conditions that is attached to the WaitSet. /// </summary> /// <param name="activeConditions">a sequence which is used to pass the list of all the attached /// conditions that have a trigger_value of true.</param> /// <param name="timeout">the maximum duration to block for the wait, after which the application thread /// is unblocked. The special constant Infinite can be used when the maximum waiting time does not /// need to be bounded.</param> /// <returns>Possible return codes for the operation are: /// Ok, Error, OutOfResources, Timeout or PreconditionNotMet</returns> public ReturnCode Wait(ref ICondition[] activeConditions, Duration timeout) { ReturnCode result = DDS.ReturnCode.Ok; ReportStack.Start(); WaitActionArg arg = new WaitActionArg(activeConditions); if (QosManager.countErrors(timeout) > 0) { result = DDS.ReturnCode.BadParameter; ReportStack.Report(result, "Duration timeout incorrect"); } while (result == DDS.ReturnCode.Ok && arg.nrTriggeredConditions == 0) { lock (this) { arg.maxConditions = conditionList.Count + guardList.Count; arg.attachedGuards = guardList.ToArray(); if (activeConditions == null) { activeConditions = new ICondition[arg.maxConditions]; } } GCHandle argGCHandle = GCHandle.Alloc(arg, GCHandleType.Normal); V_RESULT uResult = DDS.OpenSplice.User.WaitSet.WaitAction2( rlReq_UserPeer, WaitAction, GCHandle.ToIntPtr(argGCHandle), timeout.OsDuration); if (uResult == V_RESULT.DETACHING) { arg = (WaitActionArg)argGCHandle.Target; lock (this) { foreach (ICondition cond in conditionList) { Condition condImpl = cond as Condition; if (condImpl.IsAlive() == DDS.ReturnCode.AlreadyDeleted) { arg.Add(cond); } } } result = DDS.ReturnCode.Ok; } else { result = SacsSuperClass.uResultToReturnCode(uResult); arg = (WaitActionArg)argGCHandle.Target; } argGCHandle.Free(); activeConditions = arg.Finalize(); } ReportStack.Flush(this, (result != ReturnCode.Ok) && (result != ReturnCode.Timeout)); return(result); }