DDS_ReturnCode_t DDS_ContentFilteredTopic_get_expression_parameters ( DDS_ContentFilteredTopic ftp, DDS_StringSeq *expr_pars) { DDS_ReturnCode_t rc; ctrc_begind (DCPS_ID, DCPS_FT_G_PARS, &ftp, sizeof (ftp)); ctrc_contd (&expr_pars, sizeof (expr_pars)); ctrc_endd (); if (!topic_ptr (ftp, 1, NULL)) return (DDS_RETCODE_ALREADY_DELETED); if ((ftp->topic.entity.flags & EF_FILTERED) == 0) { lock_release (ftp->topic.lock); return (DDS_RETCODE_ALREADY_DELETED); } if (!expr_pars) { lock_release (ftp->topic.lock); return (DDS_RETCODE_BAD_PARAMETER); } DDS_SEQ_INIT (*expr_pars); rc = dcps_get_str_pars (expr_pars, ftp->data.filter.expression_pars); lock_release (ftp->topic.lock); return (rc); }
DDS_ReturnCode_t DDS_ContentFilteredTopic_set_expression_parameters ( DDS_ContentFilteredTopic ftp, DDS_StringSeq *expr_pars) { DDS_ReturnCode_t rc; ctrc_begind (DCPS_ID, DCPS_FT_S_PARS, &ftp, sizeof (ftp)); ctrc_contd (&expr_pars, sizeof (expr_pars)); ctrc_endd (); if (!topic_ptr (ftp, 1, NULL)) return (DDS_RETCODE_ALREADY_DELETED); if ((ftp->topic.entity.flags & EF_FILTERED) == 0) { rc = DDS_RETCODE_ALREADY_DELETED; goto done; } if (!expr_pars || DDS_SEQ_LENGTH (*expr_pars) < ftp->data.program.npars) { rc = DDS_RETCODE_BAD_PARAMETER; goto done; } rc = dcps_update_str_pars (&ftp->data.filter.expression_pars, expr_pars); done: lock_release (ftp->topic.lock); return (rc); }
DDS_TopicListener *DDS_Topic_get_listener (DDS_Topic tp) { ctrc_printd (DCPS_ID, DCPS_T_G_LIS, &tp, sizeof (tp)); if (!topic_ptr (tp, 0, NULL)) return (NULL); return (&tp->listener); }
DDS_ReturnCode_t DDS_Topic_set_qos (DDS_Topic tp, DDS_TopicQos *qos) { Endpoint_t *ep; Reader_t *rp; Writer_t *wp; DDS_ReturnCode_t ret; ctrc_begind (DCPS_ID, DCPS_T_S_QOS, &tp, sizeof (tp)); ctrc_contd (&qos, sizeof (qos)); ctrc_endd (); if (!topic_ptr (tp, 1, &ret)) return (ret); if (qos == DDS_TOPIC_QOS_DEFAULT) qos = &tp->domain->def_topic_qos; else if (!qos_valid_topic_qos (qos)) { ret = DDS_RETCODE_BAD_PARAMETER; goto done; } ret = qos_topic_update (&tp->qos, qos); if (ret != DDS_RETCODE_OK) goto done; /* Update all local Readers associated with topic. */ for (ep = tp->readers; ep; ep = ep->next) if ((ep->entity.flags & EF_LOCAL) != 0) { rp = (Reader_t *) ep; #ifdef RW_LOCKS lock_take (rp->r_lock); #endif disc_reader_update (tp->domain, rp, 1, 0); #ifdef RW_LOCKS lock_release (rp->r_lock); #endif } /* Update all local Writers associated with topic. */ for (ep = tp->writers; ep; ep = ep->next) if ((ep->entity.flags & EF_LOCAL) != 0) { wp = (Writer_t *) ep; #ifdef RW_LOCKS lock_take (wp->w_lock); #endif disc_writer_update (tp->domain, wp, 1, 0); #ifdef RW_LOCKS lock_release (wp->w_lock); #endif } done: lock_release (tp->lock); return (ret); }
DDS_InstanceHandle_t DDS_Topic_get_instance_handle (DDS_Topic tp) { DDS_InstanceHandle_t h; ctrc_printd (DCPS_ID, DCPS_T_G_HANDLE, &tp, sizeof (tp)); if (!topic_ptr (tp, 1, NULL)) return (0); h = tp->entity.handle; lock_release (tp->lock); return (h); }
DDS_StatusMask DDS_Topic_get_status_changes (DDS_Topic tp) { DDS_StatusMask m; ctrc_printd (DCPS_ID, DCPS_T_G_STAT, &tp, sizeof (tp)); if (!topic_ptr (tp, 1, NULL)) return (0); m = tp->status; lock_release (tp->lock); return (m); }
DDS_DomainParticipant DDS_Topic_get_participant (DDS_Topic topic) { Topic_t *tp; DDS_DomainParticipant part; ctrc_printd (DCPS_ID, DCPS_T_G_PART, &topic, sizeof (topic)); tp = topic_ptr (topic, 1, NULL); if (!tp) return (NULL); part = tp->domain; lock_release (tp->lock); return (part); }
const char *DDS_TopicDescription_get_type_name (DDS_TopicDescription dp) { Topic_t *tp; const char *name; ctrc_printd (DCPS_ID, DCPS_TD_G_TNAME, &dp, sizeof (dp)); tp = topic_ptr (dp, 1, NULL); if (tp) { name = str_ptr (tp->type->type_name); lock_release (tp->lock); return (name); } else return (NULL); }
DDS_DomainParticipant DDS_TopicDescription_get_participant (DDS_TopicDescription dp) { Topic_t *tp; DDS_DomainParticipant part; ctrc_printd (DCPS_ID, DCPS_TD_G_PART, &dp, sizeof (dp)); tp = topic_ptr (dp, 1, NULL); if (tp) { part = tp->domain; lock_release (tp->lock); return (part); } else return (NULL); }
const char *DDS_Topic_get_type_name (DDS_Topic topic) { Topic_t *tp; const char *name; ctrc_printd (DCPS_ID, DCPS_T_G_TNAME, &topic, sizeof (topic)); tp = topic_ptr (topic, 1, NULL); if (!tp) return (NULL); name = str_ptr (tp->type->type_name); lock_release (tp->lock); return (name); }
DDS_Topic DDS_ContentFilteredTopic_get_related_topic (DDS_ContentFilteredTopic ftp) { Topic_t *tp; ctrc_printd (DCPS_ID, DCPS_FT_REL, &ftp, sizeof (ftp)); if (!topic_ptr (ftp, 1, NULL)) return (NULL); if ((ftp->topic.entity.flags & EF_FILTERED) != 0) tp = ftp->related; else tp = NULL; lock_release (ftp->topic.lock); return (tp); }
const char *DDS_ContentFilteredTopic_get_name (DDS_ContentFilteredTopic ftp) { const char *sp; ctrc_printd (DCPS_ID, DCPS_FT_G_NAME, &ftp, sizeof (ftp)); if (!topic_ptr (ftp, 1, NULL)) return (NULL); if ((ftp->topic.entity.flags & EF_FILTERED) == 0) { lock_release (ftp->topic.lock); return (NULL); } sp = str_ptr (ftp->topic.name); lock_release (ftp->topic.lock); return (sp); }
const char *DDS_ContentFilteredTopic_get_filter_expression (DDS_ContentFilteredTopic ftp) { const char *sp; ctrc_printd (DCPS_ID, DCPS_FT_G_EXPR, &ftp, sizeof (ftp)); if (!topic_ptr (ftp, 1, NULL)) return (NULL); if ((ftp->topic.entity.flags & EF_FILTERED) != 0) sp = str_ptr (ftp->data.filter.expression); else sp = NULL; lock_release (ftp->topic.lock); return (sp); }
DDS_DomainParticipant DDS_ContentFilteredTopic_get_participant ( DDS_ContentFilteredTopic ftp) { DDS_DomainParticipant part; ctrc_printd (DCPS_ID, DCPS_FT_G_PART, &ftp, sizeof (ftp)); if (!topic_ptr (ftp, 1, NULL)) return (NULL); if ((ftp->topic.entity.flags & EF_FILTERED) != 0) part = ftp->topic.domain; else part = NULL; lock_release (ftp->topic.lock); return (part); }
DDS_ReturnCode_t DDS_Topic_get_qos (DDS_Topic tp, DDS_TopicQos *qos) { DDS_ReturnCode_t ret; ctrc_begind (DCPS_ID, DCPS_T_G_QOS, &tp, sizeof (tp)); ctrc_contd (&qos, sizeof (qos)); ctrc_endd (); if (!qos) return (DDS_RETCODE_BAD_PARAMETER); if (!topic_ptr (tp, 1, &ret)) return (ret); qos_topic_get (tp->qos, qos); lock_release (tp->lock); return (DDS_RETCODE_OK); }
DDS_ReturnCode_t DDS_Topic_enable (DDS_Topic tp) { #ifdef THREADS_USED TopicWait_t *wp; #endif DDS_ReturnCode_t error; ctrc_printd (DCPS_ID, DCPS_T_ENABLE, &tp, sizeof (tp)); if (!topic_ptr (tp, 1, &error)) return (error); if ((tp->domain->participant.p_flags & EF_ENABLED) == 0) { lock_release (tp->lock); return (DDS_RETCODE_NOT_ENABLED); } if ((tp->entity.flags & EF_ENABLED) != 0) { lock_release (tp->lock); return (DDS_RETCODE_OK); } tp->entity.flags |= (EF_NOT_IGNORED | EF_ENABLED); #ifdef THREADS_USED for (wp = tp->domain->topic_wait; wp && strcmp (wp->name, str_ptr (tp->name)); wp = wp->next) ; if (wp) { wp->topic = tp; if (wp->nthreads > 1) cond_signal_all (wp->condition); else cond_signal (wp->condition); } #endif /* Check if topic type is incompatible with learned topics. */ if ((tp->type->flags & EF_INC_TYPE) != 0) { dcps_inconsistent_topic (tp); tp->type->flags &= ~EF_INC_TYPE; } lock_release (tp->lock); return (DDS_RETCODE_OK); }
DDS_ReturnCode_t DDS_Topic_set_listener (DDS_Topic tp, DDS_TopicListener *listener, DDS_StatusMask mask) { DDS_ReturnCode_t ret; ctrc_begind (DCPS_ID, DCPS_T_S_LIS, &tp, sizeof (tp)); ctrc_contd (&listener, sizeof (listener)); ctrc_contd (&mask, sizeof (mask)); ctrc_endd (); if (!topic_ptr (tp, 1, &ret)) return (ret); dcps_update_listener ((Entity_t *) tp, &tp->lock, &tp->mask, &tp->listener, mask, listener); lock_release (tp->lock); return (DDS_RETCODE_OK); }
DDS_StatusCondition DDS_Topic_get_statuscondition (DDS_Topic tp) { StatusCondition_t *scp; ctrc_printd (DCPS_ID, DCPS_T_G_SCOND, &tp, sizeof (tp)); if (!topic_ptr (tp, 1, NULL)) return (NULL); scp = tp->condition; if (!scp) { scp = dcps_new_status_condition (); if (!scp) return (NULL); scp->entity = (Entity_t *) tp; tp->condition = scp; } lock_release (tp->lock); return ((DDS_StatusCondition) scp); }
DDS_DataReader DDS_Subscriber_create_datareader (DDS_Subscriber sp, DDS_TopicDescription topic, const DDS_DataReaderQos *qos, const DDS_DataReaderListener *listener, DDS_StatusMask mask) { Domain_t *dp; Topic_t *tp; Participant_t *pp; Reader_t *rp; Cache_t cp; EntityId_t eid; #ifdef DDS_NATIVE_SECURITY unsigned secure; DDS_ReturnCode_t ret; #endif const TypeSupport_t *ts; int error; ctrc_begind (DCPS_ID, DCPS_S_C_DR, &sp, sizeof (sp)); ctrc_contd (&topic, sizeof (topic)); ctrc_contd (&qos, sizeof (qos)); ctrc_contd (&listener, sizeof (listener)); ctrc_contd (&mask, sizeof (mask)); ctrc_endd (); prof_start (dcps_create_reader); if (!subscriber_ptr (sp, NULL)) return (NULL); dp = sp->domain; if (!dp || lock_take (dp->lock)) return (NULL); if (sp->domain != dp) goto inv_topic; /*DDS_RETCODE_BAD_PARAMETER*/ tp = topic_ptr (topic, 1, NULL); if (!tp) goto inv_topic; rp = NULL; /* Don't check whether reader is already created! Multiple readers and or writers on the same topic are definitely allowed! */ if (qos == DDS_DATAREADER_QOS_DEFAULT) qos = &sp->def_reader_qos; else if (qos != DDS_DATAREADER_QOS_USE_TOPIC_QOS && !qos_valid_reader_qos (qos)) goto done; #ifdef DDS_SECURITY /* Check if security policy allows this datareader. */ #ifdef DDS_NATIVE_SECURITY if (sec_check_create_reader (dp->participant.p_permissions, str_ptr (tp->name), NULL, qos, sp->qos.partition, NULL, &secure)) { #else if (check_create_reader (dp->participant.p_permissions, tp, qos, sp->qos.partition)) { #endif log_printf (DCPS_ID, 0, "create_datareader: reader create not allowed!\r\n"); goto done; } #endif /* Create an Entity Identifier. */ ts = tp->type->type_support; if ((sp->entity.flags & EF_BUILTIN) != 0) { eid.id [0] = eid.id [1] = 0; eid.id [2] = 0x10 + tp->type->index; eid.id [ENTITY_KIND_INDEX] = ENTITY_KIND_BUILTIN | ENTITY_KIND_READER_KEY; } else { ++dcps_entity_count; eid.id [0] = (dcps_entity_count >> 16) & 0xff; eid.id [1] = (dcps_entity_count >> 8) & 0xff; eid.id [2] = dcps_entity_count & 0xff; if (ts->ts_keys) eid.id [ENTITY_KIND_INDEX] = ENTITY_KIND_USER | ENTITY_KIND_READER_KEY; else eid.id [ENTITY_KIND_INDEX] = ENTITY_KIND_USER | ENTITY_KIND_READER; } pp = &dp->participant; rp = (Reader_t *) endpoint_create (pp, sp, &eid, NULL); if (!rp) { warn_printf ("create_datareader: out of memory for DataReader structure.\r\n"); goto done; } #ifdef RW_LOCKS lock_take (rp->r_lock); #endif if ((sp->entity.flags & EF_BUILTIN) != 0) rp->r_flags |= EF_BUILTIN; if (qos == DDS_DATAREADER_QOS_USE_TOPIC_QOS) { rp->r_qos = tp->qos; tp->qos->users++; qos_init_time_based_filter (&rp->r_time_based_filter); qos_init_reader_data_lifecycle (&rp->r_data_lifecycle); } else { rp->r_qos = qos_reader_new (qos); rp->r_time_based_filter = qos->time_based_filter; rp->r_data_lifecycle = qos->reader_data_lifecycle; } if (!rp->r_qos) goto free_pool; rp->r_mask = mask; if (listener) rp->r_listener = *listener; else memset (&rp->r_listener, 0, sizeof (rp->r_listener)); memset (&rp->r_rdm_status, 0, sizeof (rp->r_rdm_status)); memset (&rp->r_riq_status, 0, sizeof (rp->r_riq_status)); memset (&rp->r_sl_status, 0, sizeof (rp->r_sl_status)); memset (&rp->r_sr_status, 0, sizeof (rp->r_sr_status)); memset (&rp->r_lc_status, 0, sizeof (rp->r_lc_status)); memset (&rp->r_sm_status, 0, sizeof (rp->r_sm_status)); rp->r_changes.buffer = NULL; rp->r_changes.length = rp->r_changes.maximum = 0; rp->r_prev_info = NULL; rp->r_prev_data = NULL; rp->r_n_prev = 0; rp->r_topic = tp; rp->r_next = tp->readers; tp->readers = &rp->r_ep; #ifdef DDS_NATIVE_SECURITY /* Set security attributes. */ rp->r_access_prot = 0; rp->r_disc_prot = 0; rp->r_submsg_prot = 0; rp->r_payload_prot = 0; rp->r_crypto_type = 0; rp->r_crypto = 0; if (secure && (dp->participant.p_sec_caps & (SECC_DDS_SEC | (SECC_DDS_SEC << SECC_LOCAL))) != 0) { log_printf (DCPS_ID, 0, "DDS: Reader security attributes: 0x%x\r\n", secure); rp->r_access_prot = (secure & DDS_SECA_ACCESS_PROTECTED) != 0; rp->r_disc_prot = (secure & DDS_SECA_DISC_PROTECTED) != 0; rp->r_submsg_prot = (secure & DDS_SECA_SUBMSG_PROTECTED) != 0; rp->r_payload_prot = (secure & DDS_SECA_PAYLOAD_PROTECTED) != 0; if (rp->r_submsg_prot || rp->r_payload_prot) { rp->r_crypto_type = secure >> DDS_SECA_ENCRYPTION_SHIFT; rp->r_crypto = sec_register_local_datareader (dp->participant.p_crypto, rp, &ret); } }
DDS_ReturnCode_t DDS_DomainParticipant_delete_contentfilteredtopic ( DDS_DomainParticipant dp, DDS_ContentFilteredTopic ftp) { DDS_ReturnCode_t ret; ctrc_begind (DCPS_ID, DCPS_DP_D_FTOP, &dp, sizeof (dp)); ctrc_contd (&ftp, sizeof (ftp)); ctrc_endd (); prof_start (dcps_delete_ftopic); /* Get Domain Participant. */ if (!domain_ptr (dp, 1, &ret)) { log_printf (DCPS_ID, 0, "delete_filtered_topic(): domain participant not found!\r\n"); return (ret); } /* Get Topic descriptor. */ if (!topic_ptr (ftp, 0, &ret)) { lock_release (dp->lock); return (ret); } if ((ftp->topic.entity.flags & EF_FILTERED) == 0) { lock_release (dp->lock); return (DDS_RETCODE_PRECONDITION_NOT_MET); } if (ftp->topic.domain != dp || !ftp->topic.nlrefs) { log_printf (DCPS_ID, 0, "delete_filtered_topic(): invalid topic!\r\n"); lock_release (dp->lock); return (DDS_RETCODE_ALREADY_DELETED); } lock_take (ftp->topic.lock); /* Remove all references, i.e. readers/writers, of this topic. */ if (local_endpoints (ftp->topic.readers) || local_endpoints (ftp->topic.writers)) { log_printf (DCPS_ID, 0, "delete_filtered_topic(%s): still endpoints using topic!\r\n", str_ptr (ftp->topic.name)); lock_release (ftp->topic.lock); lock_release (dp->lock); return (DDS_RETCODE_PRECONDITION_NOT_MET); } if (ftp->topic.nlrefs > 1) { ftp->topic.nlrefs--; lock_release (ftp->topic.lock); lock_release (dp->lock); return (DDS_RETCODE_OK); } /* Delete topic notification data. */ memset (&ftp->topic.listener, 0, sizeof (ftp->topic.listener)); ftp->topic.mask = 0; /* Delete content filter info. */ filter_data_cleanup (&ftp->data); /* Delete topic data. */ filtered_topic_delete (ftp); lock_release (dp->lock); prof_stop (dcps_delete_ftopic, 1); return (DDS_RETCODE_OK); }
DDS_ContentFilteredTopic DDS_DomainParticipant_create_contentfilteredtopic ( DDS_DomainParticipant dp, const char *topic_name, DDS_Topic related_topic, const char *filter_expr, DDS_StringSeq *expr_pars) { Topic_t *tp; BCProgram bc_program; FilteredTopic_t *ftp; DDS_ReturnCode_t ret; int error; static const char ddssql [] = "DDSSQL"; ctrc_begind (DCPS_ID, DCPS_DP_C_FTOP, &dp, sizeof (dp)); ctrc_contd (topic_name, strlen (topic_name) + 1); ctrc_contd (related_topic, sizeof (DDS_Topic)); ctrc_contd (filter_expr, strlen (filter_expr) + 1); ctrc_contd (&expr_pars, sizeof (expr_pars)); ctrc_endd (); prof_start (dcps_create_ftopic); /* Check some required parameters. */ if (!filter_expr) return (NULL); /* Get Domain Participant. */ if (!domain_ptr (dp, 1, NULL)) { log_printf (DCPS_ID, 0, "create_topic(%s): domain doesn't exist!\r\n", topic_name); return (NULL); } /* Get Original Topic descriptor. */ tp = topic_ptr (related_topic, 1, &ret); if (!tp || tp->domain != dp) { lock_release (dp->lock); return (NULL); } #ifdef DDS_SECURITY /* Check if security policy allows this topic. */ if (check_create_topic (dp->participant.p_permissions, topic_name, NULL)) { log_printf (DCPS_ID, 0, "create_topic(%s): topic create not allowed!\r\n", topic_name); lock_release (dp->lock); return (NULL); } #endif /* Check filter validity. */ ret = sql_parse_filter (tp->type->type_support, filter_expr, &bc_program); if (ret) goto free_locks; /* Check required # of parameters. */ if (expr_pars && DDS_SEQ_LENGTH (*expr_pars) < bc_program.npars) goto free_program; /* Create the content-filtered topic. */ ftp = filtered_topic_create (dp, tp, topic_name); if (!ftp) goto free_program; /* Setup filtered topic data. */ ftp->data.filter.expression = str_new_cstr (filter_expr); if (!ftp->data.filter.expression) goto free_filtered_topic; if (expr_pars) { ftp->data.filter.expression_pars = dcps_new_str_pars (expr_pars, &error); if (!ftp->data.filter.expression_pars && error) goto pars_failed; } else ftp->data.filter.expression_pars = NULL; ftp->data.filter.name = str_ref (ftp->topic.name); ftp->data.filter.related_name = str_ref (ftp->related->name); ftp->data.filter.class_name = str_new_cstr (ddssql); if (!ftp->data.filter.name || !ftp->data.filter.related_name || !ftp->data.filter.class_name) goto pars_failed; ftp->data.program = bc_program; bc_cache_init (&ftp->data.cache); lock_release (tp->lock); lock_release (dp->lock); prof_stop (dcps_create_ftopic, 1); return (ftp); pars_failed: lock_release (tp->lock); lock_release (dp->lock); DDS_DomainParticipant_delete_contentfilteredtopic (dp, ftp); return (NULL); free_filtered_topic: filtered_topic_delete (ftp); free_program: xfree (bc_program.buffer); free_locks: lock_release (tp->lock); lock_release (dp->lock); return (NULL); }
DDS_ReturnCode_t DDS_DomainParticipant_delete_topic (DDS_DomainParticipant dp, DDS_Topic tp) { DDS_ReturnCode_t ret; Condition_t *cp; ctrc_begind (DCPS_ID, DCPS_DP_D_TOP, &dp, sizeof (dp)); ctrc_contd (&tp, sizeof (tp)); ctrc_endd (); prof_start (dcps_delete_topic_p); /* Get Domain Participant. */ if (!domain_ptr (dp, 1, &ret)) { log_printf (DCPS_ID, 0, "dcps_delete_topic(): domain participant not found!\r\n"); return (ret); } /* Get Topic descriptor. */ if (!topic_ptr (tp, 0, &ret)) { lock_release (dp->lock); return (ret); } if ((tp->entity.flags & EF_FILTERED) != 0) { lock_release (dp->lock); return (DDS_RETCODE_PRECONDITION_NOT_MET); } if (tp->domain != dp || (!tp->nlrefs && !tp->nrrefs)) { log_printf (DCPS_ID, 0, "dcps_delete_topic(): invalid topic!\r\n"); lock_release (dp->lock); return (DDS_RETCODE_ALREADY_DELETED); } lock_take (tp->lock); /* If not the last topic reference, just update the reference count. */ if (tp->nlrefs > 1 || !tp->nlrefs) { if (tp->nlrefs) tp->nlrefs--; lock_release (tp->lock); lock_release (dp->lock); return (DDS_RETCODE_OK); } /* Check if there are still references, i.e. local readers/writers, of this topic. */ if (local_endpoints (tp->readers) || local_endpoints (tp->writers)) { log_printf (DCPS_ID, 0, "dcps_delete_topic(%s): still endpoints using topic!\r\n", str_ptr (tp->name)); lock_release (tp->lock); lock_release (dp->lock); return (DDS_RETCODE_PRECONDITION_NOT_MET); } /* Last local reference. Disable event propagation to topic. */ if (!dds_purge_notifications ((Entity_t *) tp, DDS_ALL_STATUS, 1)) { lock_release (tp->lock); lock_release (dp->lock); return (DDS_RETCODE_PRECONDITION_NOT_MET); } tp->entity.flags &= ~EF_ENABLED; /* Delete topic notification data. */ memset (&tp->listener, 0, sizeof (tp->listener)); tp->mask = 0; /* Delete StatusCondition if it exists. */ if (tp->condition) { cp = (Condition_t *) tp->condition; if (cp->deferred) dds_defer_waitset_undo (tp, tp->condition); dcps_delete_status_condition (tp->condition); tp->condition = NULL; } /* Delete topic data. */ topic_delete (&dp->participant, tp, NULL, NULL); lock_release (dp->lock); prof_stop (dcps_delete_topic_p, 1); return (DDS_RETCODE_OK); }