Merge branch 'master' into security
This commit is contained in:
commit
35ce7788e1
54 changed files with 2115 additions and 1069 deletions
31
.travis.yml
31
.travis.yml
|
@ -142,37 +142,35 @@ windows_vs2017: &windows_vs2017
|
||||||
jobs:
|
jobs:
|
||||||
include:
|
include:
|
||||||
- <<: *linux_gcc8
|
- <<: *linux_gcc8
|
||||||
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, GENERATOR="Unix Makefiles", COVERITY_SCAN=true ]
|
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, LIFESPAN=YES, GENERATOR="Unix Makefiles", COVERITY_SCAN=true ]
|
||||||
if: type = cron
|
if: type = cron
|
||||||
- <<: *linux_gcc8
|
- <<: *linux_gcc8
|
||||||
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, GENERATOR="Unix Makefiles" ]
|
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, LIFESPAN=YES, GENERATOR="Unix Makefiles" ]
|
||||||
- <<: *linux_gcc8
|
- <<: *linux_gcc8
|
||||||
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=YES, SECURITY=YES, GENERATOR="Unix Makefiles" ]
|
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=YES, SECURITY=YES, LIFESPAN=YES, GENERATOR="Unix Makefiles" ]
|
||||||
- <<: *linux_gcc8
|
- <<: *linux_gcc8
|
||||||
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Debug, SSL=NO, SECURITY=YES, GENERATOR="Unix Makefiles" ]
|
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Debug, SSL=NO, SECURITY=YES, LIFESPAN=NO, GENERATOR="Unix Makefiles" ]
|
||||||
- <<: *linux_gcc8
|
- <<: *linux_gcc8
|
||||||
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=YES, SECURITY=YES, GENERATOR="Unix Makefiles" ]
|
env: [ ARCH=x86_64, ASAN=address, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, LIFESPAN=YES, GENERATOR="Unix Makefiles" ]
|
||||||
- <<: *linux_clang
|
- <<: *linux_clang
|
||||||
env: [ ARCH=x86_64, ASAN=address, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, GENERATOR="Unix Makefiles" ]
|
env: [ ARCH=x86_64, ASAN=address, BUILD_TYPE=Debug, SSL=YES, SECURITY=NO, LIFESPAN=YES, GENERATOR="Unix Makefiles" ]
|
||||||
- <<: *linux_clang
|
- <<: *linux_clang
|
||||||
env: [ ARCH=x86_64, ASAN=address, BUILD_TYPE=Debug, SSL=YES, SECURITY=NO, GENERATOR="Unix Makefiles" ]
|
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=YES, SECURITY=YES, LIFESPAN=YES, GENERATOR="Unix Makefiles" ]
|
||||||
- <<: *linux_clang
|
|
||||||
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=YES, SECURITY=YES, GENERATOR="Unix Makefiles" ]
|
|
||||||
- <<: *osx_xcode9
|
- <<: *osx_xcode9
|
||||||
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=NO, SECURITY=YES, GENERATOR="Unix Makefiles" ]
|
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=NO, SECURITY=YES, LIFESPAN=YES, GENERATOR="Unix Makefiles" ]
|
||||||
if: type = cron
|
if: type = cron
|
||||||
- <<: *osx_xcode
|
- <<: *osx_xcode
|
||||||
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=NO, SECURITY=YES, GENERATOR="Unix Makefiles", MACOSX_DEPLOYMENT_TARGET=10.12 ]
|
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=NO, SECURITY=YES, LIFESPAN=YES, GENERATOR="Unix Makefiles", MACOSX_DEPLOYMENT_TARGET=10.12 ]
|
||||||
- <<: *osx_xcode
|
- <<: *osx_xcode
|
||||||
env: [ ARCH=x86_64, ASAN=address, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, GENERATOR="Unix Makefiles" ]
|
env: [ ARCH=x86_64, ASAN=address, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, LIFESPAN=YES, GENERATOR="Unix Makefiles" ]
|
||||||
- <<: *osx_xcode
|
- <<: *osx_xcode
|
||||||
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=YES, SECURITY=YES, GENERATOR="Unix Makefiles" ]
|
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=YES, SECURITY=YES, LIFESPAN=YES, GENERATOR="Unix Makefiles" ]
|
||||||
- <<: *windows_vs2017
|
- <<: *windows_vs2017
|
||||||
env: [ ARCH=x86, ASAN=none, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, GENERATOR="Visual Studio 15 2017" ]
|
env: [ ARCH=x86, ASAN=none, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, LIFESPAN=YES, GENERATOR="Visual Studio 15 2017" ]
|
||||||
- <<: *windows_vs2017
|
- <<: *windows_vs2017
|
||||||
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, GENERATOR="Visual Studio 15 2017 Win64" ]
|
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, LIFESPAN=YES, GENERATOR="Visual Studio 15 2017 Win64" ]
|
||||||
- <<: *windows_vs2017
|
- <<: *windows_vs2017
|
||||||
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=YES, SECURITY=YES, GENERATOR="Visual Studio 15 2017 Win64" ]
|
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=YES, SECURITY=YES, LIFESPAN=YES, GENERATOR="Visual Studio 15 2017 Win64" ]
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- conan profile new default --detect
|
- conan profile new default --detect
|
||||||
|
@ -204,6 +202,7 @@ script:
|
||||||
-DUSE_SANITIZER=${ASAN}
|
-DUSE_SANITIZER=${ASAN}
|
||||||
-DENABLE_SSL=${SSL}
|
-DENABLE_SSL=${SSL}
|
||||||
-DENABLE_SECURITY=${SECURITY}
|
-DENABLE_SECURITY=${SECURITY}
|
||||||
|
-DENABLE_LIFESPAN=${LIFESPAN}
|
||||||
-DBUILD_TESTING=on
|
-DBUILD_TESTING=on
|
||||||
-DWERROR=on
|
-DWERROR=on
|
||||||
-G "${GENERATOR}" ..
|
-G "${GENERATOR}" ..
|
||||||
|
|
|
@ -27,6 +27,11 @@ endif()
|
||||||
|
|
||||||
add_definitions(-DDDSI_INCLUDE_NETWORK_PARTITIONS -DDDSI_INCLUDE_SSM)
|
add_definitions(-DDDSI_INCLUDE_NETWORK_PARTITIONS -DDDSI_INCLUDE_SSM)
|
||||||
|
|
||||||
|
option(ENABLE_LIFESPAN "Enable Lifespan QoS support" ON)
|
||||||
|
if(ENABLE_LIFESPAN)
|
||||||
|
add_definitions(-DDDSI_INCLUDE_LIFESPAN)
|
||||||
|
endif()
|
||||||
|
|
||||||
# OpenSSL is huge, raising the RSS by 1MB or so, and moreover find_package(OpenSSL) causes
|
# OpenSSL is huge, raising the RSS by 1MB or so, and moreover find_package(OpenSSL) causes
|
||||||
# trouble on some older CMake versions that otherwise work fine, so provide an option to avoid
|
# trouble on some older CMake versions that otherwise work fine, so provide an option to avoid
|
||||||
# all OpenSSL related things.
|
# all OpenSSL related things.
|
||||||
|
|
|
@ -20,9 +20,12 @@ struct dds_rhc;
|
||||||
struct dds_reader;
|
struct dds_reader;
|
||||||
struct ddsi_sertopic;
|
struct ddsi_sertopic;
|
||||||
struct q_globals;
|
struct q_globals;
|
||||||
|
struct dds_rhc_default;
|
||||||
|
struct rhc_sample;
|
||||||
|
|
||||||
DDS_EXPORT struct dds_rhc *dds_rhc_default_new_xchecks (dds_reader *reader, struct q_globals *gv, const struct ddsi_sertopic *topic, bool xchecks);
|
DDS_EXPORT struct dds_rhc *dds_rhc_default_new_xchecks (dds_reader *reader, struct q_globals *gv, const struct ddsi_sertopic *topic, bool xchecks);
|
||||||
DDS_EXPORT struct dds_rhc *dds_rhc_default_new (struct dds_reader *reader, const struct ddsi_sertopic *topic);
|
DDS_EXPORT struct dds_rhc *dds_rhc_default_new (struct dds_reader *reader, const struct ddsi_sertopic *topic);
|
||||||
|
DDS_EXPORT nn_mtime_t dds_rhc_default_sample_expired_cb(void *hc, nn_mtime_t tnow);
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct whc *builtintopic_whc_new (enum ddsi_sertopic_builtintopic_type type, const struct ephash *guid_hash);
|
struct whc *builtintopic_whc_new (enum ddsi_sertopic_builtintopic_type type, const struct entity_index *entidx);
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,10 +257,12 @@ void dds__builtin_init (struct dds_domain *dom)
|
||||||
dom->builtin_reader_topic = new_sertopic_builtintopic (DSBT_READER, "DCPSSubscription", "org::eclipse::cyclonedds::builtin::DCPSSubscription", &dom->gv);
|
dom->builtin_reader_topic = new_sertopic_builtintopic (DSBT_READER, "DCPSSubscription", "org::eclipse::cyclonedds::builtin::DCPSSubscription", &dom->gv);
|
||||||
dom->builtin_writer_topic = new_sertopic_builtintopic (DSBT_WRITER, "DCPSPublication", "org::eclipse::cyclonedds::builtin::DCPSPublication", &dom->gv);
|
dom->builtin_writer_topic = new_sertopic_builtintopic (DSBT_WRITER, "DCPSPublication", "org::eclipse::cyclonedds::builtin::DCPSPublication", &dom->gv);
|
||||||
|
|
||||||
const struct ephash *gh = dom->gv.guid_hash;
|
thread_state_awake (lookup_thread_state (), &dom->gv);
|
||||||
|
const struct entity_index *gh = dom->gv.entity_index;
|
||||||
dom->builtintopic_writer_participant = new_local_orphan_writer (&dom->gv, to_entityid (NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER), dom->builtin_participant_topic, qos, builtintopic_whc_new (DSBT_PARTICIPANT, gh));
|
dom->builtintopic_writer_participant = new_local_orphan_writer (&dom->gv, to_entityid (NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER), dom->builtin_participant_topic, qos, builtintopic_whc_new (DSBT_PARTICIPANT, gh));
|
||||||
dom->builtintopic_writer_publications = new_local_orphan_writer (&dom->gv, to_entityid (NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER), dom->builtin_writer_topic, qos, builtintopic_whc_new (DSBT_WRITER, gh));
|
dom->builtintopic_writer_publications = new_local_orphan_writer (&dom->gv, to_entityid (NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER), dom->builtin_writer_topic, qos, builtintopic_whc_new (DSBT_WRITER, gh));
|
||||||
dom->builtintopic_writer_subscriptions = new_local_orphan_writer (&dom->gv, to_entityid (NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER), dom->builtin_reader_topic, qos, builtintopic_whc_new (DSBT_READER, gh));
|
dom->builtintopic_writer_subscriptions = new_local_orphan_writer (&dom->gv, to_entityid (NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER), dom->builtin_reader_topic, qos, builtintopic_whc_new (DSBT_READER, gh));
|
||||||
|
thread_state_asleep (lookup_thread_state ());
|
||||||
|
|
||||||
dds_delete_qos (qos);
|
dds_delete_qos (qos);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include "dds__guardcond.h"
|
#include "dds__guardcond.h"
|
||||||
#include "dds__participant.h"
|
#include "dds__participant.h"
|
||||||
#include "dds/ddsi/ddsi_iid.h"
|
#include "dds/ddsi/ddsi_iid.h"
|
||||||
#include "dds/ddsi/q_ephash.h"
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
#include "dds/ddsi/q_thread.h"
|
#include "dds/ddsi/q_thread.h"
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "dds/ddsi/q_config.h"
|
#include "dds/ddsi/q_config.h"
|
||||||
#include "dds/ddsi/q_globals.h"
|
#include "dds/ddsi/q_globals.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/ddsi/q_thread.h"
|
#include "dds/ddsi/q_thread.h"
|
||||||
#include "dds/ddsi/q_bswap.h"
|
#include "dds/ddsi/q_bswap.h"
|
||||||
#include "dds__writer.h"
|
#include "dds__writer.h"
|
||||||
|
@ -33,7 +34,7 @@ dds_return_t dds_get_matched_subscriptions (dds_entity_t writer, dds_instance_ha
|
||||||
return rc;
|
return rc;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const struct ephash *gh = wr->m_entity.m_domain->gv.guid_hash;
|
const struct entity_index *gh = wr->m_entity.m_domain->gv.entity_index;
|
||||||
size_t nrds_act = 0;
|
size_t nrds_act = 0;
|
||||||
ddsrt_avl_iter_t it;
|
ddsrt_avl_iter_t it;
|
||||||
/* FIXME: this ought not be so tightly coupled to the lower layer */
|
/* FIXME: this ought not be so tightly coupled to the lower layer */
|
||||||
|
@ -44,7 +45,7 @@ dds_return_t dds_get_matched_subscriptions (dds_entity_t writer, dds_instance_ha
|
||||||
m = ddsrt_avl_iter_next (&it))
|
m = ddsrt_avl_iter_next (&it))
|
||||||
{
|
{
|
||||||
struct proxy_reader *prd;
|
struct proxy_reader *prd;
|
||||||
if ((prd = ephash_lookup_proxy_reader_guid (gh, &m->prd_guid)) != NULL)
|
if ((prd = entidx_lookup_proxy_reader_guid (gh, &m->prd_guid)) != NULL)
|
||||||
{
|
{
|
||||||
if (nrds_act < nrds)
|
if (nrds_act < nrds)
|
||||||
rds[nrds_act] = prd->e.iid;
|
rds[nrds_act] = prd->e.iid;
|
||||||
|
@ -56,7 +57,7 @@ dds_return_t dds_get_matched_subscriptions (dds_entity_t writer, dds_instance_ha
|
||||||
m = ddsrt_avl_iter_next (&it))
|
m = ddsrt_avl_iter_next (&it))
|
||||||
{
|
{
|
||||||
struct reader *rd;
|
struct reader *rd;
|
||||||
if ((rd = ephash_lookup_reader_guid (gh, &m->rd_guid)) != NULL)
|
if ((rd = entidx_lookup_reader_guid (gh, &m->rd_guid)) != NULL)
|
||||||
{
|
{
|
||||||
if (nrds_act < nrds)
|
if (nrds_act < nrds)
|
||||||
rds[nrds_act] = rd->e.iid;
|
rds[nrds_act] = rd->e.iid;
|
||||||
|
@ -83,7 +84,7 @@ dds_return_t dds_get_matched_publications (dds_entity_t reader, dds_instance_han
|
||||||
return rc;
|
return rc;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const struct ephash *gh = rd->m_entity.m_domain->gv.guid_hash;
|
const struct entity_index *gh = rd->m_entity.m_domain->gv.entity_index;
|
||||||
size_t nwrs_act = 0;
|
size_t nwrs_act = 0;
|
||||||
ddsrt_avl_iter_t it;
|
ddsrt_avl_iter_t it;
|
||||||
/* FIXME: this ought not be so tightly coupled to the lower layer */
|
/* FIXME: this ought not be so tightly coupled to the lower layer */
|
||||||
|
@ -94,7 +95,7 @@ dds_return_t dds_get_matched_publications (dds_entity_t reader, dds_instance_han
|
||||||
m = ddsrt_avl_iter_next (&it))
|
m = ddsrt_avl_iter_next (&it))
|
||||||
{
|
{
|
||||||
struct proxy_writer *pwr;
|
struct proxy_writer *pwr;
|
||||||
if ((pwr = ephash_lookup_proxy_writer_guid (gh, &m->pwr_guid)) != NULL)
|
if ((pwr = entidx_lookup_proxy_writer_guid (gh, &m->pwr_guid)) != NULL)
|
||||||
{
|
{
|
||||||
if (nwrs_act < nwrs)
|
if (nwrs_act < nwrs)
|
||||||
wrs[nwrs_act] = pwr->e.iid;
|
wrs[nwrs_act] = pwr->e.iid;
|
||||||
|
@ -106,7 +107,7 @@ dds_return_t dds_get_matched_publications (dds_entity_t reader, dds_instance_han
|
||||||
m = ddsrt_avl_iter_next (&it))
|
m = ddsrt_avl_iter_next (&it))
|
||||||
{
|
{
|
||||||
struct writer *wr;
|
struct writer *wr;
|
||||||
if ((wr = ephash_lookup_writer_guid (gh, &m->wr_guid)) != NULL)
|
if ((wr = entidx_lookup_writer_guid (gh, &m->wr_guid)) != NULL)
|
||||||
{
|
{
|
||||||
if (nwrs_act < nwrs)
|
if (nwrs_act < nwrs)
|
||||||
wrs[nwrs_act] = wr->e.iid;
|
wrs[nwrs_act] = wr->e.iid;
|
||||||
|
@ -148,7 +149,7 @@ dds_builtintopic_endpoint_t *dds_get_matched_subscription_data (dds_entity_t wri
|
||||||
return NULL;
|
return NULL;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const struct ephash *gh = wr->m_entity.m_domain->gv.guid_hash;
|
const struct entity_index *gh = wr->m_entity.m_domain->gv.entity_index;
|
||||||
dds_builtintopic_endpoint_t *ret = NULL;
|
dds_builtintopic_endpoint_t *ret = NULL;
|
||||||
ddsrt_avl_iter_t it;
|
ddsrt_avl_iter_t it;
|
||||||
/* FIXME: this ought not be so tightly coupled to the lower layer, and not be so inefficient besides */
|
/* FIXME: this ought not be so tightly coupled to the lower layer, and not be so inefficient besides */
|
||||||
|
@ -159,7 +160,7 @@ dds_builtintopic_endpoint_t *dds_get_matched_subscription_data (dds_entity_t wri
|
||||||
m = ddsrt_avl_iter_next (&it))
|
m = ddsrt_avl_iter_next (&it))
|
||||||
{
|
{
|
||||||
struct proxy_reader *prd;
|
struct proxy_reader *prd;
|
||||||
if ((prd = ephash_lookup_proxy_reader_guid (gh, &m->prd_guid)) != NULL)
|
if ((prd = entidx_lookup_proxy_reader_guid (gh, &m->prd_guid)) != NULL)
|
||||||
{
|
{
|
||||||
if (prd->e.iid == ih)
|
if (prd->e.iid == ih)
|
||||||
ret = make_builtintopic_endpoint (&prd->e.guid, &prd->c.proxypp->e.guid, prd->c.proxypp->e.iid, prd->c.xqos);
|
ret = make_builtintopic_endpoint (&prd->e.guid, &prd->c.proxypp->e.guid, prd->c.proxypp->e.iid, prd->c.xqos);
|
||||||
|
@ -170,7 +171,7 @@ dds_builtintopic_endpoint_t *dds_get_matched_subscription_data (dds_entity_t wri
|
||||||
m = ddsrt_avl_iter_next (&it))
|
m = ddsrt_avl_iter_next (&it))
|
||||||
{
|
{
|
||||||
struct reader *rd;
|
struct reader *rd;
|
||||||
if ((rd = ephash_lookup_reader_guid (gh, &m->rd_guid)) != NULL)
|
if ((rd = entidx_lookup_reader_guid (gh, &m->rd_guid)) != NULL)
|
||||||
{
|
{
|
||||||
if (rd->e.iid == ih)
|
if (rd->e.iid == ih)
|
||||||
ret = make_builtintopic_endpoint (&rd->e.guid, &rd->c.pp->e.guid, rd->c.pp->e.iid, rd->xqos);
|
ret = make_builtintopic_endpoint (&rd->e.guid, &rd->c.pp->e.guid, rd->c.pp->e.iid, rd->xqos);
|
||||||
|
@ -191,7 +192,7 @@ dds_builtintopic_endpoint_t *dds_get_matched_publication_data (dds_entity_t read
|
||||||
return NULL;
|
return NULL;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const struct ephash *gh = rd->m_entity.m_domain->gv.guid_hash;
|
const struct entity_index *gh = rd->m_entity.m_domain->gv.entity_index;
|
||||||
dds_builtintopic_endpoint_t *ret = NULL;
|
dds_builtintopic_endpoint_t *ret = NULL;
|
||||||
ddsrt_avl_iter_t it;
|
ddsrt_avl_iter_t it;
|
||||||
/* FIXME: this ought not be so tightly coupled to the lower layer, and not be so inefficient besides */
|
/* FIXME: this ought not be so tightly coupled to the lower layer, and not be so inefficient besides */
|
||||||
|
@ -202,7 +203,7 @@ dds_builtintopic_endpoint_t *dds_get_matched_publication_data (dds_entity_t read
|
||||||
m = ddsrt_avl_iter_next (&it))
|
m = ddsrt_avl_iter_next (&it))
|
||||||
{
|
{
|
||||||
struct proxy_writer *pwr;
|
struct proxy_writer *pwr;
|
||||||
if ((pwr = ephash_lookup_proxy_writer_guid (gh, &m->pwr_guid)) != NULL)
|
if ((pwr = entidx_lookup_proxy_writer_guid (gh, &m->pwr_guid)) != NULL)
|
||||||
{
|
{
|
||||||
if (pwr->e.iid == ih)
|
if (pwr->e.iid == ih)
|
||||||
ret = make_builtintopic_endpoint (&pwr->e.guid, &pwr->c.proxypp->e.guid, pwr->c.proxypp->e.iid, pwr->c.xqos);
|
ret = make_builtintopic_endpoint (&pwr->e.guid, &pwr->c.proxypp->e.guid, pwr->c.proxypp->e.iid, pwr->c.xqos);
|
||||||
|
@ -213,7 +214,7 @@ dds_builtintopic_endpoint_t *dds_get_matched_publication_data (dds_entity_t read
|
||||||
m = ddsrt_avl_iter_next (&it))
|
m = ddsrt_avl_iter_next (&it))
|
||||||
{
|
{
|
||||||
struct writer *wr;
|
struct writer *wr;
|
||||||
if ((wr = ephash_lookup_writer_guid (gh, &m->wr_guid)) != NULL)
|
if ((wr = entidx_lookup_writer_guid (gh, &m->wr_guid)) != NULL)
|
||||||
{
|
{
|
||||||
if (wr->e.iid == ih)
|
if (wr->e.iid == ih)
|
||||||
ret = make_builtintopic_endpoint (&wr->e.guid, &wr->c.pp->e.guid, wr->c.pp->e.iid, wr->xqos);
|
ret = make_builtintopic_endpoint (&wr->e.guid, &wr->c.pp->e.guid, wr->c.pp->e.iid, wr->xqos);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "dds/ddsi/q_config.h"
|
#include "dds/ddsi/q_config.h"
|
||||||
#include "dds/ddsi/q_plist.h"
|
#include "dds/ddsi/q_plist.h"
|
||||||
#include "dds/ddsi/q_globals.h"
|
#include "dds/ddsi/q_globals.h"
|
||||||
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/version.h"
|
#include "dds/version.h"
|
||||||
#include "dds__init.h"
|
#include "dds__init.h"
|
||||||
#include "dds__domain.h"
|
#include "dds__domain.h"
|
||||||
|
@ -55,7 +56,7 @@ static dds_return_t dds_participant_qos_set (dds_entity *e, const dds_qos_t *qos
|
||||||
{
|
{
|
||||||
struct participant *pp;
|
struct participant *pp;
|
||||||
thread_state_awake (lookup_thread_state (), &e->m_domain->gv);
|
thread_state_awake (lookup_thread_state (), &e->m_domain->gv);
|
||||||
if ((pp = ephash_lookup_participant_guid (e->m_domain->gv.guid_hash, &e->m_guid)) != NULL)
|
if ((pp = entidx_lookup_participant_guid (e->m_domain->gv.entity_index, &e->m_guid)) != NULL)
|
||||||
{
|
{
|
||||||
nn_plist_t plist;
|
nn_plist_t plist;
|
||||||
nn_plist_init_empty (&plist);
|
nn_plist_init_empty (&plist);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include "dds/ddsi/ddsi_tkmap.h"
|
#include "dds/ddsi/ddsi_tkmap.h"
|
||||||
#include "dds/ddsc/dds_rhc.h"
|
#include "dds/ddsc/dds_rhc.h"
|
||||||
#include "dds/ddsi/q_thread.h"
|
#include "dds/ddsi/q_thread.h"
|
||||||
#include "dds/ddsi/q_ephash.h"
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
#include "dds/ddsi/q_globals.h"
|
#include "dds/ddsi/q_globals.h"
|
||||||
#include "dds/ddsi/ddsi_sertopic.h"
|
#include "dds/ddsi/ddsi_sertopic.h"
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include "dds/ddsc/dds_rhc.h"
|
#include "dds/ddsc/dds_rhc.h"
|
||||||
#include "dds__entity.h"
|
#include "dds__entity.h"
|
||||||
#include "dds/ddsi/ddsi_iid.h"
|
#include "dds/ddsi/ddsi_iid.h"
|
||||||
#include "dds/ddsi/q_ephash.h"
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
#include "dds/ddsi/q_thread.h"
|
#include "dds/ddsi/q_thread.h"
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "dds/ddsi/q_globals.h"
|
#include "dds/ddsi/q_globals.h"
|
||||||
#include "dds__builtin.h"
|
#include "dds__builtin.h"
|
||||||
#include "dds/ddsi/ddsi_sertopic.h"
|
#include "dds/ddsi/ddsi_sertopic.h"
|
||||||
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
|
|
||||||
DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_reader)
|
DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_reader)
|
||||||
|
|
||||||
|
@ -77,7 +78,7 @@ static dds_return_t dds_reader_qos_set (dds_entity *e, const dds_qos_t *qos, boo
|
||||||
{
|
{
|
||||||
struct reader *rd;
|
struct reader *rd;
|
||||||
thread_state_awake (lookup_thread_state (), &e->m_domain->gv);
|
thread_state_awake (lookup_thread_state (), &e->m_domain->gv);
|
||||||
if ((rd = ephash_lookup_reader_guid (e->m_domain->gv.guid_hash, &e->m_guid)) != NULL)
|
if ((rd = entidx_lookup_reader_guid (e->m_domain->gv.entity_index, &e->m_guid)) != NULL)
|
||||||
update_reader_qos (rd, qos);
|
update_reader_qos (rd, qos);
|
||||||
thread_state_asleep (lookup_thread_state ());
|
thread_state_asleep (lookup_thread_state ());
|
||||||
}
|
}
|
||||||
|
@ -512,7 +513,7 @@ void dds_reader_ddsi2direct (dds_entity_t entity, ddsi2direct_directread_cb_t cb
|
||||||
pwrguid_next.entityid.u = (pwrguid_next.entityid.u & ~(uint32_t)0xff) | NN_ENTITYID_KIND_WRITER_NO_KEY;
|
pwrguid_next.entityid.u = (pwrguid_next.entityid.u & ~(uint32_t)0xff) | NN_ENTITYID_KIND_WRITER_NO_KEY;
|
||||||
}
|
}
|
||||||
ddsrt_mutex_unlock (&rd->e.lock);
|
ddsrt_mutex_unlock (&rd->e.lock);
|
||||||
if ((pwr = ephash_lookup_proxy_writer_guid (dds_entity->m_domain->gv.guid_hash, &pwrguid)) != NULL)
|
if ((pwr = entidx_lookup_proxy_writer_guid (dds_entity->m_domain->gv.entity_index, &pwrguid)) != NULL)
|
||||||
{
|
{
|
||||||
ddsrt_mutex_lock (&pwr->e.lock);
|
ddsrt_mutex_lock (&pwr->e.lock);
|
||||||
pwr->ddsi2direct_cb = cb;
|
pwr->ddsi2direct_cb = cb;
|
||||||
|
|
|
@ -39,6 +39,9 @@
|
||||||
#include "dds/ddsi/q_entity.h" /* proxy_writer_info */
|
#include "dds/ddsi/q_entity.h" /* proxy_writer_info */
|
||||||
#include "dds/ddsi/ddsi_serdata.h"
|
#include "dds/ddsi/ddsi_serdata.h"
|
||||||
#include "dds/ddsi/ddsi_serdata_default.h"
|
#include "dds/ddsi/ddsi_serdata_default.h"
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
#include "dds/ddsi/ddsi_lifespan.h"
|
||||||
|
#endif
|
||||||
#include "dds/ddsi/sysdeps.h"
|
#include "dds/ddsi/sysdeps.h"
|
||||||
|
|
||||||
/* INSTANCE MANAGEMENT
|
/* INSTANCE MANAGEMENT
|
||||||
|
@ -122,9 +125,8 @@
|
||||||
DDSI implementation, but still) will be done by also reseting "wr_iid"
|
DDSI implementation, but still) will be done by also reseting "wr_iid"
|
||||||
when an exclusive ownership writer lowers its strength.
|
when an exclusive ownership writer lowers its strength.
|
||||||
|
|
||||||
Lifespan, time base filter and deadline, are based on the instance
|
Lifespan is based on the reception timestamp, and the monotonic time is
|
||||||
timestamp ("tstamp"). This time stamp needs to be changed to either source
|
used for sample expiry if this QoS is set to something else than infinite.
|
||||||
or reception timestamp, depending on the ordering chosen.
|
|
||||||
|
|
||||||
READ CONDITIONS
|
READ CONDITIONS
|
||||||
===============
|
===============
|
||||||
|
@ -244,6 +246,10 @@ struct rhc_sample {
|
||||||
bool isread; /* READ or NOT_READ sample state */
|
bool isread; /* READ or NOT_READ sample state */
|
||||||
uint32_t disposed_gen; /* snapshot of instance counter at time of insertion */
|
uint32_t disposed_gen; /* snapshot of instance counter at time of insertion */
|
||||||
uint32_t no_writers_gen; /* __/ */
|
uint32_t no_writers_gen; /* __/ */
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
struct lifespan_fhnode lifespan; /* fibheap node for lifespan */
|
||||||
|
struct rhc_instance *inst; /* reference to rhc instance */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rhc_instance {
|
struct rhc_instance {
|
||||||
|
@ -289,15 +295,15 @@ struct dds_rhc_default {
|
||||||
int32_t max_samples; /* FIXME: probably better as uint32_t with MAX_UINT32 for unlimited */
|
int32_t max_samples; /* FIXME: probably better as uint32_t with MAX_UINT32 for unlimited */
|
||||||
int32_t max_samples_per_instance; /* FIXME: probably better as uint32_t with MAX_UINT32 for unlimited */
|
int32_t max_samples_per_instance; /* FIXME: probably better as uint32_t with MAX_UINT32 for unlimited */
|
||||||
|
|
||||||
uint32_t n_instances; /* # instances, including empty [NOT USED] */
|
uint32_t n_instances; /* # instances, including empty */
|
||||||
uint32_t n_nonempty_instances; /* # non-empty instances */
|
uint32_t n_nonempty_instances; /* # non-empty instances */
|
||||||
uint32_t n_not_alive_disposed; /* # disposed, non-empty instances [NOT USED] */
|
uint32_t n_not_alive_disposed; /* # disposed, non-empty instances */
|
||||||
uint32_t n_not_alive_no_writers; /* # not-alive-no-writers, non-empty instances [NOT USED] */
|
uint32_t n_not_alive_no_writers; /* # not-alive-no-writers, non-empty instances */
|
||||||
uint32_t n_new; /* # new, non-empty instances [NOT USED] */
|
uint32_t n_new; /* # new, non-empty instances */
|
||||||
uint32_t n_vsamples; /* # "valid" samples over all instances */
|
uint32_t n_vsamples; /* # "valid" samples over all instances */
|
||||||
uint32_t n_vread; /* # read "valid" samples over all instances [NOT USED] */
|
uint32_t n_vread; /* # read "valid" samples over all instances */
|
||||||
uint32_t n_invsamples; /* # invalid samples over all instances [NOT USED] */
|
uint32_t n_invsamples; /* # invalid samples over all instances */
|
||||||
uint32_t n_invread; /* # read invalid samples over all instances [NOT USED] */
|
uint32_t n_invread; /* # read invalid samples over all instances */
|
||||||
|
|
||||||
bool by_source_ordering; /* true if BY_SOURCE, false if BY_RECEPTION */
|
bool by_source_ordering; /* true if BY_SOURCE, false if BY_RECEPTION */
|
||||||
bool exclusive_ownership; /* true if EXCLUSIVE, false if SHARED */
|
bool exclusive_ownership; /* true if EXCLUSIVE, false if SHARED */
|
||||||
|
@ -316,6 +322,9 @@ struct dds_rhc_default {
|
||||||
uint32_t nqconds; /* Number of associated query conditions */
|
uint32_t nqconds; /* Number of associated query conditions */
|
||||||
dds_querycond_mask_t qconds_samplest; /* Mask of associated query conditions that check the sample state */
|
dds_querycond_mask_t qconds_samplest; /* Mask of associated query conditions that check the sample state */
|
||||||
void *qcond_eval_samplebuf; /* Temporary storage for evaluating query conditions, NULL if no qconds */
|
void *qcond_eval_samplebuf; /* Temporary storage for evaluating query conditions, NULL if no qconds */
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
struct lifespan_adm lifespan; /* Lifespan administration */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct trigger_info_cmn {
|
struct trigger_info_cmn {
|
||||||
|
@ -460,6 +469,11 @@ static void topicless_to_clean_invsample (const struct ddsi_sertopic *topic, con
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned qmask_of_inst (const struct rhc_instance *inst);
|
static unsigned qmask_of_inst (const struct rhc_instance *inst);
|
||||||
|
static void free_sample (struct dds_rhc_default *rhc, struct rhc_instance *inst, struct rhc_sample *s);
|
||||||
|
static void get_trigger_info_cmn (struct trigger_info_cmn *info, struct rhc_instance *inst);
|
||||||
|
static void get_trigger_info_pre (struct trigger_info_pre *info, struct rhc_instance *inst);
|
||||||
|
static void init_trigger_info_qcond (struct trigger_info_qcond *qc);
|
||||||
|
static void drop_instance_noupdate_no_writers (struct dds_rhc_default *rhc, struct rhc_instance *inst);
|
||||||
static bool update_conditions_locked (struct dds_rhc_default *rhc, bool called_from_insert, const struct trigger_info_pre *pre, const struct trigger_info_post *post, const struct trigger_info_qcond *trig_qc, const struct rhc_instance *inst, struct dds_entity *triggers[], size_t *ntriggers);
|
static bool update_conditions_locked (struct dds_rhc_default *rhc, bool called_from_insert, const struct trigger_info_pre *pre, const struct trigger_info_post *post, const struct trigger_info_qcond *trig_qc, const struct rhc_instance *inst, struct dds_entity *triggers[], size_t *ntriggers);
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
static int rhc_check_counts_locked (struct dds_rhc_default *rhc, bool check_conds, bool check_qcmask);
|
static int rhc_check_counts_locked (struct dds_rhc_default *rhc, bool check_conds, bool check_qcmask);
|
||||||
|
@ -531,6 +545,83 @@ static void remove_inst_from_nonempty_list (struct dds_rhc_default *rhc, struct
|
||||||
rhc->n_nonempty_instances--;
|
rhc->n_nonempty_instances--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
static void drop_expired_samples (struct dds_rhc_default *rhc, struct rhc_sample *sample)
|
||||||
|
{
|
||||||
|
struct rhc_instance *inst = sample->inst;
|
||||||
|
struct trigger_info_pre pre;
|
||||||
|
struct trigger_info_post post;
|
||||||
|
struct trigger_info_qcond trig_qc;
|
||||||
|
size_t ntriggers = SIZE_MAX;
|
||||||
|
|
||||||
|
assert (!inst_is_empty (inst));
|
||||||
|
|
||||||
|
TRACE ("rhc_default %p drop_exp(iid %"PRIx64" wriid %"PRIx64" exp %"PRId64" %s",
|
||||||
|
rhc, inst->iid, sample->wr_iid, sample->lifespan.t_expire.v, sample->isread ? "read" : "notread");
|
||||||
|
|
||||||
|
get_trigger_info_pre (&pre, inst);
|
||||||
|
init_trigger_info_qcond (&trig_qc);
|
||||||
|
|
||||||
|
/* Find prev sample: in case of history depth of 1 this is the sample itself,
|
||||||
|
* (which is inst->latest). In case of larger history depth the most likely sample
|
||||||
|
* to be expired is the oldest, in which case inst->latest is the previous
|
||||||
|
* sample and inst->latest->next points to sample (circular list). We can
|
||||||
|
* assume that 'sample' is in the list, so a check to avoid infinite loop is not
|
||||||
|
* required here. */
|
||||||
|
struct rhc_sample *psample = inst->latest;
|
||||||
|
while (psample->next != sample)
|
||||||
|
psample = psample->next;
|
||||||
|
|
||||||
|
rhc->n_vsamples--;
|
||||||
|
if (sample->isread)
|
||||||
|
{
|
||||||
|
inst->nvread--;
|
||||||
|
rhc->n_vread--;
|
||||||
|
trig_qc.dec_sample_read = true;
|
||||||
|
}
|
||||||
|
if (--inst->nvsamples > 0)
|
||||||
|
{
|
||||||
|
if (inst->latest == sample)
|
||||||
|
inst->latest = psample;
|
||||||
|
psample->next = sample->next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inst->latest = NULL;
|
||||||
|
}
|
||||||
|
trig_qc.dec_conds_sample = sample->conds;
|
||||||
|
free_sample (rhc, inst, sample);
|
||||||
|
get_trigger_info_cmn (&post.c, inst);
|
||||||
|
update_conditions_locked (rhc, false, &pre, &post, &trig_qc, inst, NULL, &ntriggers);
|
||||||
|
if (inst_is_empty (inst))
|
||||||
|
{
|
||||||
|
remove_inst_from_nonempty_list (rhc, inst);
|
||||||
|
if (inst->isdisposed)
|
||||||
|
rhc->n_not_alive_disposed--;
|
||||||
|
if (inst->wrcount == 0)
|
||||||
|
{
|
||||||
|
TRACE ("; iid %"PRIx64" #0,empty,drop", inst->iid);
|
||||||
|
if (!inst->isdisposed)
|
||||||
|
rhc->n_not_alive_no_writers--;
|
||||||
|
drop_instance_noupdate_no_writers (rhc, inst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TRACE (")\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
nn_mtime_t dds_rhc_default_sample_expired_cb(void *hc, nn_mtime_t tnow)
|
||||||
|
{
|
||||||
|
struct dds_rhc_default *rhc = hc;
|
||||||
|
struct rhc_sample *sample;
|
||||||
|
nn_mtime_t tnext;
|
||||||
|
ddsrt_mutex_lock (&rhc->lock);
|
||||||
|
while ((tnext = lifespan_next_expired_locked (&rhc->lifespan, tnow, (void **)&sample)).v == 0)
|
||||||
|
drop_expired_samples (rhc, sample);
|
||||||
|
ddsrt_mutex_unlock (&rhc->lock);
|
||||||
|
return tnext;
|
||||||
|
}
|
||||||
|
#endif /* DDSI_INCLUDE_LIFESPAN */
|
||||||
|
|
||||||
struct dds_rhc *dds_rhc_default_new_xchecks (dds_reader *reader, struct q_globals *gv, const struct ddsi_sertopic *topic, bool xchecks)
|
struct dds_rhc *dds_rhc_default_new_xchecks (dds_reader *reader, struct q_globals *gv, const struct ddsi_sertopic *topic, bool xchecks)
|
||||||
{
|
{
|
||||||
struct dds_rhc_default *rhc = ddsrt_malloc (sizeof (*rhc));
|
struct dds_rhc_default *rhc = ddsrt_malloc (sizeof (*rhc));
|
||||||
|
@ -546,6 +637,10 @@ struct dds_rhc *dds_rhc_default_new_xchecks (dds_reader *reader, struct q_global
|
||||||
rhc->gv = gv;
|
rhc->gv = gv;
|
||||||
rhc->xchecks = xchecks;
|
rhc->xchecks = xchecks;
|
||||||
|
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
lifespan_init (gv, &rhc->lifespan, offsetof(struct dds_rhc_default, lifespan), offsetof(struct rhc_sample, lifespan), dds_rhc_default_sample_expired_cb);
|
||||||
|
#endif
|
||||||
|
|
||||||
return &rhc->common;
|
return &rhc->common;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -601,9 +696,15 @@ static struct rhc_sample *alloc_sample (struct rhc_instance *inst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_sample (struct rhc_instance *inst, struct rhc_sample *s)
|
static void free_sample (struct dds_rhc_default *rhc, struct rhc_instance *inst, struct rhc_sample *s)
|
||||||
{
|
{
|
||||||
|
#ifndef DDSI_INCLUDE_LIFESPAN
|
||||||
|
DDSRT_UNUSED_ARG (rhc);
|
||||||
|
#endif
|
||||||
ddsi_serdata_unref (s->sample);
|
ddsi_serdata_unref (s->sample);
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
lifespan_unregister_sample_locked (&rhc->lifespan, &s->lifespan);
|
||||||
|
#endif
|
||||||
if (s == &inst->a_sample)
|
if (s == &inst->a_sample)
|
||||||
{
|
{
|
||||||
assert (!inst->a_sample_free);
|
assert (!inst->a_sample_free);
|
||||||
|
@ -665,11 +766,12 @@ static void free_instance_rhc_free (struct rhc_instance *inst, struct dds_rhc_de
|
||||||
struct rhc_sample *s = inst->latest;
|
struct rhc_sample *s = inst->latest;
|
||||||
const bool was_empty = inst_is_empty (inst);
|
const bool was_empty = inst_is_empty (inst);
|
||||||
struct trigger_info_qcond dummy_trig_qc;
|
struct trigger_info_qcond dummy_trig_qc;
|
||||||
|
|
||||||
if (s)
|
if (s)
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
struct rhc_sample * const s1 = s->next;
|
struct rhc_sample * const s1 = s->next;
|
||||||
free_sample (inst, s);
|
free_sample (rhc, inst, s);
|
||||||
s = s1;
|
s = s1;
|
||||||
} while (s != inst->latest);
|
} while (s != inst->latest);
|
||||||
rhc->n_vsamples -= inst->nvsamples;
|
rhc->n_vsamples -= inst->nvsamples;
|
||||||
|
@ -682,11 +784,10 @@ static void free_instance_rhc_free (struct rhc_instance *inst, struct dds_rhc_de
|
||||||
#endif
|
#endif
|
||||||
inst_clear_invsample_if_exists (rhc, inst, &dummy_trig_qc);
|
inst_clear_invsample_if_exists (rhc, inst, &dummy_trig_qc);
|
||||||
if (!was_empty)
|
if (!was_empty)
|
||||||
{
|
|
||||||
remove_inst_from_nonempty_list (rhc, inst);
|
remove_inst_from_nonempty_list (rhc, inst);
|
||||||
}
|
if (inst->isnew)
|
||||||
ddsi_tkmap_instance_unref (rhc->tkmap, inst->tk);
|
rhc->n_new--;
|
||||||
ddsrt_free (inst);
|
free_empty_instance(inst, rhc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t dds_rhc_default_lock_samples (struct dds_rhc_default *rhc)
|
static uint32_t dds_rhc_default_lock_samples (struct dds_rhc_default *rhc)
|
||||||
|
@ -708,7 +809,10 @@ static void free_instance_rhc_free_wrap (void *vnode, void *varg)
|
||||||
|
|
||||||
static void dds_rhc_default_free (struct dds_rhc_default *rhc)
|
static void dds_rhc_default_free (struct dds_rhc_default *rhc)
|
||||||
{
|
{
|
||||||
assert (rhc_check_counts_locked (rhc, true, true));
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
dds_rhc_default_sample_expired_cb (rhc, NN_MTIME_NEVER);
|
||||||
|
lifespan_fini (&rhc->lifespan);
|
||||||
|
#endif
|
||||||
ddsrt_hh_enum (rhc->instances, free_instance_rhc_free_wrap, rhc);
|
ddsrt_hh_enum (rhc->instances, free_instance_rhc_free_wrap, rhc);
|
||||||
assert (rhc->nonempty_instances == NULL);
|
assert (rhc->nonempty_instances == NULL);
|
||||||
ddsrt_hh_free (rhc->instances);
|
ddsrt_hh_free (rhc->instances);
|
||||||
|
@ -789,6 +893,10 @@ static bool add_sample (struct dds_rhc_default *rhc, struct rhc_instance *inst,
|
||||||
assert (trig_qc->dec_conds_sample == 0);
|
assert (trig_qc->dec_conds_sample == 0);
|
||||||
ddsi_serdata_unref (s->sample);
|
ddsi_serdata_unref (s->sample);
|
||||||
|
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
lifespan_unregister_sample_locked (&rhc->lifespan, &s->lifespan);
|
||||||
|
#endif
|
||||||
|
|
||||||
trig_qc->dec_sample_read = s->isread;
|
trig_qc->dec_sample_read = s->isread;
|
||||||
trig_qc->dec_conds_sample = s->conds;
|
trig_qc->dec_conds_sample = s->conds;
|
||||||
if (s->isread)
|
if (s->isread)
|
||||||
|
@ -843,6 +951,11 @@ static bool add_sample (struct dds_rhc_default *rhc, struct rhc_instance *inst,
|
||||||
s->isread = false;
|
s->isread = false;
|
||||||
s->disposed_gen = inst->disposed_gen;
|
s->disposed_gen = inst->disposed_gen;
|
||||||
s->no_writers_gen = inst->no_writers_gen;
|
s->no_writers_gen = inst->no_writers_gen;
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
s->inst = inst;
|
||||||
|
s->lifespan.t_expire = wrinfo->lifespan_exp;
|
||||||
|
lifespan_register_sample_locked (&rhc->lifespan, &s->lifespan);
|
||||||
|
#endif
|
||||||
|
|
||||||
s->conds = 0;
|
s->conds = 0;
|
||||||
if (rhc->nqconds != 0)
|
if (rhc->nqconds != 0)
|
||||||
|
@ -939,6 +1052,8 @@ static void drop_instance_noupdate_no_writers (struct dds_rhc_default *rhc, stru
|
||||||
assert (inst_is_empty (inst));
|
assert (inst_is_empty (inst));
|
||||||
|
|
||||||
rhc->n_instances--;
|
rhc->n_instances--;
|
||||||
|
if (inst->isnew)
|
||||||
|
rhc->n_new--;
|
||||||
|
|
||||||
ret = ddsrt_hh_remove (rhc->instances, inst);
|
ret = ddsrt_hh_remove (rhc->instances, inst);
|
||||||
assert (ret);
|
assert (ret);
|
||||||
|
@ -1065,7 +1180,6 @@ static void account_for_empty_to_nonempty_transition (struct dds_rhc_default *rh
|
||||||
{
|
{
|
||||||
assert (inst_nsamples (inst) == 1);
|
assert (inst_nsamples (inst) == 1);
|
||||||
add_inst_to_nonempty_list (rhc, inst);
|
add_inst_to_nonempty_list (rhc, inst);
|
||||||
rhc->n_new += inst->isnew;
|
|
||||||
if (inst->isdisposed)
|
if (inst->isdisposed)
|
||||||
rhc->n_not_alive_disposed++;
|
rhc->n_not_alive_disposed++;
|
||||||
else if (inst->wrcount == 0)
|
else if (inst->wrcount == 0)
|
||||||
|
@ -1294,6 +1408,7 @@ static rhc_store_result_t rhc_store_new_instance (struct rhc_instance **out_inst
|
||||||
assert (ret);
|
assert (ret);
|
||||||
(void) ret;
|
(void) ret;
|
||||||
rhc->n_instances++;
|
rhc->n_instances++;
|
||||||
|
rhc->n_new++;
|
||||||
get_trigger_info_cmn (&post->c, inst);
|
get_trigger_info_cmn (&post->c, inst);
|
||||||
|
|
||||||
*out_inst = inst;
|
*out_inst = inst;
|
||||||
|
@ -1486,16 +1601,10 @@ static bool dds_rhc_default_store (struct dds_rhc_default * __restrict rhc, cons
|
||||||
if (inst->latest || inst_became_disposed)
|
if (inst->latest || inst_became_disposed)
|
||||||
{
|
{
|
||||||
if (was_empty)
|
if (was_empty)
|
||||||
{
|
|
||||||
/* general function is slightly slower than a specialised
|
|
||||||
one, but perhaps it is wiser to use the general one */
|
|
||||||
account_for_empty_to_nonempty_transition (rhc, inst);
|
account_for_empty_to_nonempty_transition (rhc, inst);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
rhc->n_not_alive_disposed += (uint32_t)(inst->isdisposed - old_isdisposed);
|
rhc->n_not_alive_disposed += (uint32_t)(inst->isdisposed - old_isdisposed);
|
||||||
rhc->n_new += (uint32_t)(inst->isnew - old_isnew);
|
rhc->n_new += (uint32_t)(inst->isnew - old_isnew);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2032,7 +2141,7 @@ static int dds_rhc_take_w_qminv (struct dds_rhc_default *rhc, bool lock, void **
|
||||||
inst->latest = NULL;
|
inst->latest = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
free_sample (inst, sample);
|
free_sample (rhc, inst, sample);
|
||||||
|
|
||||||
if (++n == max_samples)
|
if (++n == max_samples)
|
||||||
{
|
{
|
||||||
|
@ -2179,7 +2288,7 @@ static int dds_rhc_takecdr_w_qminv (struct dds_rhc_default *rhc, bool lock, stru
|
||||||
else
|
else
|
||||||
inst->latest = NULL;
|
inst->latest = NULL;
|
||||||
|
|
||||||
free_sample (inst, sample);
|
free_sample (rhc, inst, sample);
|
||||||
|
|
||||||
if (++n == max_samples)
|
if (++n == max_samples)
|
||||||
{
|
{
|
||||||
|
@ -2442,7 +2551,11 @@ static bool update_conditions_locked (struct dds_rhc_default *rhc, bool called_f
|
||||||
trig_qc->dec_conds_invsample, trig_qc->dec_conds_sample, trig_qc->inc_conds_invsample, trig_qc->inc_conds_sample);
|
trig_qc->dec_conds_invsample, trig_qc->dec_conds_sample, trig_qc->inc_conds_invsample, trig_qc->inc_conds_sample);
|
||||||
|
|
||||||
assert (rhc->n_nonempty_instances >= rhc->n_not_alive_disposed + rhc->n_not_alive_no_writers);
|
assert (rhc->n_nonempty_instances >= rhc->n_not_alive_disposed + rhc->n_not_alive_no_writers);
|
||||||
|
#ifndef DDSI_INCLUDE_LIFESPAN
|
||||||
|
/* If lifespan is disabled, samples cannot expire and therefore
|
||||||
|
empty instances cannot be in the 'new' state. */
|
||||||
assert (rhc->n_nonempty_instances >= rhc->n_new);
|
assert (rhc->n_nonempty_instances >= rhc->n_new);
|
||||||
|
#endif
|
||||||
assert (rhc->n_vsamples >= rhc->n_vread);
|
assert (rhc->n_vsamples >= rhc->n_vread);
|
||||||
|
|
||||||
iter = rhc->conds;
|
iter = rhc->conds;
|
||||||
|
@ -2687,6 +2800,8 @@ static int rhc_check_counts_locked (struct dds_rhc_default *rhc, bool check_cond
|
||||||
bool a_sample_free = true;
|
bool a_sample_free = true;
|
||||||
|
|
||||||
n_instances++;
|
n_instances++;
|
||||||
|
if (inst->isnew)
|
||||||
|
n_new++;
|
||||||
if (inst_is_empty (inst))
|
if (inst_is_empty (inst))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -2695,8 +2810,6 @@ static int rhc_check_counts_locked (struct dds_rhc_default *rhc, bool check_cond
|
||||||
n_not_alive_disposed++;
|
n_not_alive_disposed++;
|
||||||
else if (inst->wrcount == 0)
|
else if (inst->wrcount == 0)
|
||||||
n_not_alive_no_writers++;
|
n_not_alive_no_writers++;
|
||||||
if (inst->isnew)
|
|
||||||
n_new++;
|
|
||||||
|
|
||||||
if (inst->latest)
|
if (inst->latest)
|
||||||
{
|
{
|
||||||
|
@ -2790,9 +2903,7 @@ static int rhc_check_counts_locked (struct dds_rhc_default *rhc, bool check_cond
|
||||||
if (check_conds)
|
if (check_conds)
|
||||||
{
|
{
|
||||||
for (i = 0, rciter = rhc->conds; i < ncheck; i++, rciter = rciter->m_next)
|
for (i = 0, rciter = rhc->conds; i < ncheck; i++, rciter = rciter->m_next)
|
||||||
{
|
|
||||||
assert (cond_match_count[i] == ddsrt_atomic_ld32 (&rciter->m_entity.m_status.m_trigger));
|
assert (cond_match_count[i] == ddsrt_atomic_ld32 (&rciter->m_entity.m_status.m_trigger));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rhc->n_nonempty_instances == 0)
|
if (rhc->n_nonempty_instances == 0)
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "dds__serdata_builtintopic.h"
|
#include "dds__serdata_builtintopic.h"
|
||||||
#include "dds/ddsi/ddsi_tkmap.h"
|
#include "dds/ddsi/ddsi_tkmap.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
|
|
||||||
static const uint64_t unihashconsts[] = {
|
static const uint64_t unihashconsts[] = {
|
||||||
UINT64_C (16292676669999574021),
|
UINT64_C (16292676669999574021),
|
||||||
|
@ -131,7 +132,7 @@ static struct ddsi_serdata *ddsi_serdata_builtin_from_keyhash (const struct ddsi
|
||||||
/* FIXME: not quite elegant to manage the creation of a serdata for a built-in topic via this function, but I also find it quite unelegant to let from_sample read straight from the underlying internal entity, and to_sample convert to the external format ... I could claim the internal entity is the "serialised form", but that forces wrapping it in a fragchain in one way or another, which, though possible, is also a bit lacking in elegance. */
|
/* FIXME: not quite elegant to manage the creation of a serdata for a built-in topic via this function, but I also find it quite unelegant to let from_sample read straight from the underlying internal entity, and to_sample convert to the external format ... I could claim the internal entity is the "serialised form", but that forces wrapping it in a fragchain in one way or another, which, though possible, is also a bit lacking in elegance. */
|
||||||
const struct ddsi_sertopic_builtintopic *tp = (const struct ddsi_sertopic_builtintopic *)tpcmn;
|
const struct ddsi_sertopic_builtintopic *tp = (const struct ddsi_sertopic_builtintopic *)tpcmn;
|
||||||
/* keyhash must in host format (which the GUIDs always are internally) */
|
/* keyhash must in host format (which the GUIDs always are internally) */
|
||||||
struct entity_common *entity = ephash_lookup_guid_untyped (tp->gv->guid_hash, (const ddsi_guid_t *) keyhash->value);
|
struct entity_common *entity = entidx_lookup_guid_untyped (tp->gv->entity_index, (const ddsi_guid_t *) keyhash->value);
|
||||||
struct ddsi_serdata_builtintopic *d = serdata_builtin_new(tp, entity ? SDK_DATA : SDK_KEY);
|
struct ddsi_serdata_builtintopic *d = serdata_builtin_new(tp, entity ? SDK_DATA : SDK_KEY);
|
||||||
memcpy (&d->key, keyhash->value, sizeof (d->key));
|
memcpy (&d->key, keyhash->value, sizeof (d->key));
|
||||||
if (entity)
|
if (entity)
|
||||||
|
|
|
@ -1288,9 +1288,12 @@ static void dds_stream_extract_key_from_key_prim_op (dds_istream_t * __restrict
|
||||||
#if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN
|
#if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN
|
||||||
static void dds_stream_swap_copy (void * __restrict vdst, const void * __restrict vsrc, uint32_t size, uint32_t num)
|
static void dds_stream_swap_copy (void * __restrict vdst, const void * __restrict vsrc, uint32_t size, uint32_t num)
|
||||||
{
|
{
|
||||||
assert (size == 2 || size == 4 || size == 8);
|
assert (size == 1 || size == 2 || size == 4 || size == 8);
|
||||||
switch (size)
|
switch (size)
|
||||||
{
|
{
|
||||||
|
case 1:
|
||||||
|
memcpy (vdst, vsrc, num);
|
||||||
|
break;
|
||||||
case 2: {
|
case 2: {
|
||||||
const uint16_t *src = vsrc;
|
const uint16_t *src = vsrc;
|
||||||
uint16_t *dst = vdst;
|
uint16_t *dst = vdst;
|
||||||
|
@ -1342,7 +1345,7 @@ static void dds_stream_extract_keyBE_from_key_prim_op (dds_istream_t * __restric
|
||||||
void const * const src = is->m_buffer + is->m_index;
|
void const * const src = is->m_buffer + is->m_index;
|
||||||
void * const dst = os->x.m_buffer + os->x.m_index;
|
void * const dst = os->x.m_buffer + os->x.m_index;
|
||||||
#if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN
|
#if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN
|
||||||
dds_stream_swap_copy (dst, src, num, align);
|
dds_stream_swap_copy (dst, src, align, num);
|
||||||
#else
|
#else
|
||||||
memcpy (dst, src, num * align);
|
memcpy (dst, src, num * align);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1722,7 +1725,7 @@ static bool prtf_simple_array (char * __restrict *buf, size_t * __restrict bufsi
|
||||||
abort ();
|
abort ();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return cont;
|
return prtf (buf, bufsize, "}");
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool dds_stream_print_sample1 (char * __restrict *buf, size_t * __restrict bufsize, dds_istream_t * __restrict is, const uint32_t * __restrict ops, bool add_braces);
|
static bool dds_stream_print_sample1 (char * __restrict *buf, size_t * __restrict bufsize, dds_istream_t * __restrict is, const uint32_t * __restrict ops, bool add_braces);
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "dds__get_status.h"
|
#include "dds__get_status.h"
|
||||||
#include "dds__qos.h"
|
#include "dds__qos.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/ddsi/q_thread.h"
|
#include "dds/ddsi/q_thread.h"
|
||||||
#include "dds/ddsi/ddsi_sertopic.h"
|
#include "dds/ddsi/ddsi_sertopic.h"
|
||||||
#include "dds/ddsi/q_ddsi_discovery.h"
|
#include "dds/ddsi/q_ddsi_discovery.h"
|
||||||
|
@ -437,7 +438,7 @@ dds_entity_t dds_create_topic_arbitrary (dds_entity_t participant, struct ddsi_s
|
||||||
|
|
||||||
/* Publish Topic */
|
/* Publish Topic */
|
||||||
thread_state_awake (lookup_thread_state (), &par->m_entity.m_domain->gv);
|
thread_state_awake (lookup_thread_state (), &par->m_entity.m_domain->gv);
|
||||||
ddsi_pp = ephash_lookup_participant_guid (par->m_entity.m_domain->gv.guid_hash, &par->m_entity.m_guid);
|
ddsi_pp = entidx_lookup_participant_guid (par->m_entity.m_domain->gv.entity_index, &par->m_entity.m_guid);
|
||||||
assert (ddsi_pp);
|
assert (ddsi_pp);
|
||||||
if (sedp_plist)
|
if (sedp_plist)
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,25 +12,28 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "dds/ddsrt/heap.h"
|
#include "dds/ddsrt/heap.h"
|
||||||
#include "dds/ddsrt/sync.h"
|
#include "dds/ddsrt/sync.h"
|
||||||
#include "dds/ddsrt/misc.h"
|
#include "dds/ddsrt/misc.h"
|
||||||
|
#include "dds/ddsrt/avl.h"
|
||||||
|
#include "dds/ddsrt/fibheap.h"
|
||||||
|
#include "dds/ddsrt/hopscotch.h"
|
||||||
#include "dds/ddsi/ddsi_serdata.h"
|
#include "dds/ddsi/ddsi_serdata.h"
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
#include "dds/ddsi/ddsi_lifespan.h"
|
||||||
|
#endif
|
||||||
#include "dds/ddsi/q_unused.h"
|
#include "dds/ddsi/q_unused.h"
|
||||||
#include "dds/ddsi/q_config.h"
|
#include "dds/ddsi/q_config.h"
|
||||||
#include "dds__whc.h"
|
|
||||||
#include "dds/ddsi/ddsi_tkmap.h"
|
#include "dds/ddsi/ddsi_tkmap.h"
|
||||||
|
|
||||||
#include "dds/ddsrt/avl.h"
|
|
||||||
#include "dds/ddsrt/hopscotch.h"
|
|
||||||
#include "dds/ddsi/q_time.h"
|
#include "dds/ddsi/q_time.h"
|
||||||
#include "dds/ddsi/q_rtps.h"
|
#include "dds/ddsi/q_rtps.h"
|
||||||
#include "dds/ddsi/q_freelist.h"
|
#include "dds/ddsi/q_freelist.h"
|
||||||
#include "dds/ddsi/q_globals.h"
|
#include "dds/ddsi/q_globals.h"
|
||||||
|
#include "dds__whc.h"
|
||||||
|
|
||||||
#define USE_EHH 0
|
#define USE_EHH 0
|
||||||
|
|
||||||
|
|
||||||
struct whc_node {
|
struct whc_node {
|
||||||
struct whc_node *next_seq; /* next in this interval */
|
struct whc_node *next_seq; /* next in this interval */
|
||||||
struct whc_node *prev_seq; /* prev in this interval */
|
struct whc_node *prev_seq; /* prev in this interval */
|
||||||
|
@ -44,6 +47,9 @@ struct whc_node {
|
||||||
unsigned borrowed: 1; /* at most one can borrow it at any time */
|
unsigned borrowed: 1; /* at most one can borrow it at any time */
|
||||||
nn_mtime_t last_rexmit_ts;
|
nn_mtime_t last_rexmit_ts;
|
||||||
uint32_t rexmit_count;
|
uint32_t rexmit_count;
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
struct lifespan_fhnode lifespan; /* fibheap node for lifespan */
|
||||||
|
#endif
|
||||||
struct ddsi_serdata *serdata;
|
struct ddsi_serdata *serdata;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -95,6 +101,9 @@ struct whc_impl {
|
||||||
#endif
|
#endif
|
||||||
struct ddsrt_hh *idx_hash;
|
struct ddsrt_hh *idx_hash;
|
||||||
ddsrt_avl_tree_t seq;
|
ddsrt_avl_tree_t seq;
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
struct lifespan_adm lifespan; /* Lifespan administration */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct whc_sample_iter_impl {
|
struct whc_sample_iter_impl {
|
||||||
|
@ -128,7 +137,7 @@ static uint32_t whc_default_remove_acked_messages_full (struct whc_impl *whc, se
|
||||||
static uint32_t whc_default_remove_acked_messages (struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list);
|
static uint32_t whc_default_remove_acked_messages (struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list);
|
||||||
static void whc_default_free_deferred_free_list (struct whc *whc, struct whc_node *deferred_free_list);
|
static void whc_default_free_deferred_free_list (struct whc *whc, struct whc_node *deferred_free_list);
|
||||||
static void whc_default_get_state (const struct whc *whc, struct whc_state *st);
|
static void whc_default_get_state (const struct whc *whc, struct whc_state *st);
|
||||||
static int whc_default_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk);
|
static int whc_default_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, nn_mtime_t exp, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk);
|
||||||
static seqno_t whc_default_next_seq (const struct whc *whc, seqno_t seq);
|
static seqno_t whc_default_next_seq (const struct whc *whc, seqno_t seq);
|
||||||
static bool whc_default_borrow_sample (const struct whc *whc, seqno_t seq, struct whc_borrowed_sample *sample);
|
static bool whc_default_borrow_sample (const struct whc *whc, seqno_t seq, struct whc_borrowed_sample *sample);
|
||||||
static bool whc_default_borrow_sample_key (const struct whc *whc, const struct ddsi_serdata *serdata_key, struct whc_borrowed_sample *sample);
|
static bool whc_default_borrow_sample_key (const struct whc *whc, const struct ddsi_serdata *serdata_key, struct whc_borrowed_sample *sample);
|
||||||
|
@ -349,6 +358,21 @@ static struct whc_node *whc_findkey (const struct whc_impl *whc, const struct dd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
static nn_mtime_t whc_sample_expired_cb(void *hc, nn_mtime_t tnow)
|
||||||
|
{
|
||||||
|
struct whc_impl *whc = hc;
|
||||||
|
void *sample;
|
||||||
|
nn_mtime_t tnext;
|
||||||
|
ddsrt_mutex_lock (&whc->lock);
|
||||||
|
while ((tnext = lifespan_next_expired_locked (&whc->lifespan, tnow, &sample)).v == 0)
|
||||||
|
whc_delete_one (whc, sample);
|
||||||
|
whc->maxseq_node = whc_findmax_procedurally (whc);
|
||||||
|
ddsrt_mutex_unlock (&whc->lock);
|
||||||
|
return tnext;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
struct whc *whc_new (struct q_globals *gv, int is_transient_local, uint32_t hdepth, uint32_t tldepth)
|
struct whc *whc_new (struct q_globals *gv, int is_transient_local, uint32_t hdepth, uint32_t tldepth)
|
||||||
{
|
{
|
||||||
size_t sample_overhead = 80; /* INFO_TS, DATA (estimate), inline QoS */
|
size_t sample_overhead = 80; /* INFO_TS, DATA (estimate), inline QoS */
|
||||||
|
@ -384,6 +408,10 @@ struct whc *whc_new (struct q_globals *gv, int is_transient_local, uint32_t hdep
|
||||||
else
|
else
|
||||||
whc->idx_hash = NULL;
|
whc->idx_hash = NULL;
|
||||||
|
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
lifespan_init (gv, &whc->lifespan, offsetof(struct whc_impl, lifespan), offsetof(struct whc_node, lifespan), whc_sample_expired_cb);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* seq interval tree: always has an "open" node */
|
/* seq interval tree: always has an "open" node */
|
||||||
ddsrt_avl_init (&whc_seq_treedef, &whc->seq);
|
ddsrt_avl_init (&whc_seq_treedef, &whc->seq);
|
||||||
intv = ddsrt_malloc (sizeof (*intv));
|
intv = ddsrt_malloc (sizeof (*intv));
|
||||||
|
@ -417,6 +445,11 @@ void whc_default_free (struct whc *whc_generic)
|
||||||
struct whc_impl * const whc = (struct whc_impl *)whc_generic;
|
struct whc_impl * const whc = (struct whc_impl *)whc_generic;
|
||||||
check_whc (whc);
|
check_whc (whc);
|
||||||
|
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
whc_sample_expired_cb (whc, NN_MTIME_NEVER);
|
||||||
|
lifespan_fini (&whc->lifespan);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (whc->idx_hash)
|
if (whc->idx_hash)
|
||||||
{
|
{
|
||||||
struct ddsrt_hh_iter it;
|
struct ddsrt_hh_iter it;
|
||||||
|
@ -686,6 +719,10 @@ static void whc_delete_one_intv (struct whc_impl *whc, struct whc_intvnode **p_i
|
||||||
whcn->unacked = 0;
|
whcn->unacked = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
lifespan_unregister_sample_locked (&whc->lifespan, &whcn->lifespan);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Take it out of seqhash; deleting it from the list ordered on
|
/* Take it out of seqhash; deleting it from the list ordered on
|
||||||
sequence numbers is left to the caller (it has to be done unconditionally,
|
sequence numbers is left to the caller (it has to be done unconditionally,
|
||||||
but remove_acked_messages defers it until the end or a skipped node). */
|
but remove_acked_messages defers it until the end or a skipped node). */
|
||||||
|
@ -869,6 +906,9 @@ static uint32_t whc_default_remove_acked_messages_noidx (struct whc_impl *whc, s
|
||||||
whc->unacked_bytes -= (size_t) (whcn->total_bytes - (*deferred_free_list)->total_bytes + (*deferred_free_list)->size);
|
whc->unacked_bytes -= (size_t) (whcn->total_bytes - (*deferred_free_list)->total_bytes + (*deferred_free_list)->size);
|
||||||
for (whcn = *deferred_free_list; whcn; whcn = whcn->next_seq)
|
for (whcn = *deferred_free_list; whcn; whcn = whcn->next_seq)
|
||||||
{
|
{
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
lifespan_unregister_sample_locked (&whc->lifespan, &whcn->lifespan);
|
||||||
|
#endif
|
||||||
remove_whcn_from_hash (whc, whcn);
|
remove_whcn_from_hash (whc, whcn);
|
||||||
assert (whcn->unacked);
|
assert (whcn->unacked);
|
||||||
}
|
}
|
||||||
|
@ -1035,10 +1075,16 @@ static uint32_t whc_default_remove_acked_messages (struct whc *whc_generic, seqn
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct whc_node *whc_default_insert_seq (struct whc_impl *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata)
|
static struct whc_node *whc_default_insert_seq (struct whc_impl *whc, seqno_t max_drop_seq, seqno_t seq, nn_mtime_t exp, struct nn_plist *plist, struct ddsi_serdata *serdata)
|
||||||
{
|
{
|
||||||
struct whc_node *newn = NULL;
|
struct whc_node *newn = NULL;
|
||||||
|
|
||||||
|
#ifndef DDSI_INCLUDE_LIFESPAN
|
||||||
|
/* FIXME: the 'exp' arg is used for lifespan, refactor this parameter to a struct 'writer info'
|
||||||
|
that contains both lifespan and deadline info of the writer */
|
||||||
|
DDSRT_UNUSED_ARG (exp);
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((newn = nn_freelist_pop (&whc_node_freelist)) == NULL)
|
if ((newn = nn_freelist_pop (&whc_node_freelist)) == NULL)
|
||||||
newn = ddsrt_malloc (sizeof (*newn));
|
newn = ddsrt_malloc (sizeof (*newn));
|
||||||
newn->seq = seq;
|
newn->seq = seq;
|
||||||
|
@ -1062,6 +1108,10 @@ static struct whc_node *whc_default_insert_seq (struct whc_impl *whc, seqno_t ma
|
||||||
if (newn->unacked)
|
if (newn->unacked)
|
||||||
whc->unacked_bytes += newn->size;
|
whc->unacked_bytes += newn->size;
|
||||||
|
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
newn->lifespan.t_expire = exp;
|
||||||
|
#endif
|
||||||
|
|
||||||
insert_whcn_in_hash (whc, newn);
|
insert_whcn_in_hash (whc, newn);
|
||||||
|
|
||||||
if (whc->open_intv->first == NULL)
|
if (whc->open_intv->first == NULL)
|
||||||
|
@ -1093,10 +1143,13 @@ static struct whc_node *whc_default_insert_seq (struct whc_impl *whc, seqno_t ma
|
||||||
}
|
}
|
||||||
|
|
||||||
whc->seq_size++;
|
whc->seq_size++;
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
lifespan_register_sample_locked (&whc->lifespan, &newn->lifespan);
|
||||||
|
#endif
|
||||||
return newn;
|
return newn;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk)
|
static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, seqno_t seq, nn_mtime_t exp, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk)
|
||||||
{
|
{
|
||||||
struct whc_impl * const whc = (struct whc_impl *)whc_generic;
|
struct whc_impl * const whc = (struct whc_impl *)whc_generic;
|
||||||
struct whc_node *newn = NULL;
|
struct whc_node *newn = NULL;
|
||||||
|
@ -1106,6 +1159,9 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
|
||||||
char pad[sizeof (struct whc_idxnode) + sizeof (struct whc_node *)];
|
char pad[sizeof (struct whc_idxnode) + sizeof (struct whc_node *)];
|
||||||
} template;
|
} template;
|
||||||
|
|
||||||
|
/* FIXME: the 'exp' arg is used for lifespan, refactor this parameter to a struct 'writer info'
|
||||||
|
that contains both lifespan als deadline info of the writer */
|
||||||
|
|
||||||
ddsrt_mutex_lock (&whc->lock);
|
ddsrt_mutex_lock (&whc->lock);
|
||||||
check_whc (whc);
|
check_whc (whc);
|
||||||
|
|
||||||
|
@ -1113,8 +1169,8 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
|
||||||
{
|
{
|
||||||
struct whc_state whcst;
|
struct whc_state whcst;
|
||||||
get_state_locked (whc, &whcst);
|
get_state_locked (whc, &whcst);
|
||||||
TRACE ("whc_default_insert(%p max_drop_seq %"PRId64" seq %"PRId64" plist %p serdata %p:%"PRIx32")\n",
|
TRACE ("whc_default_insert(%p max_drop_seq %"PRId64" seq %"PRId64" exp %"PRId64" plist %p serdata %p:%"PRIx32")\n",
|
||||||
(void *) whc, max_drop_seq, seq, (void *) plist, (void *) serdata, serdata->hash);
|
(void *) whc, max_drop_seq, seq, exp.v, (void *) plist, (void *) serdata, serdata->hash);
|
||||||
TRACE (" whc: [%"PRId64",%"PRId64"] max_drop_seq %"PRId64" h %"PRIu32" tl %"PRIu32"\n",
|
TRACE (" whc: [%"PRId64",%"PRId64"] max_drop_seq %"PRId64" h %"PRIu32" tl %"PRIu32"\n",
|
||||||
whcst.min_seq, whcst.max_seq, whc->max_drop_seq, whc->hdepth, whc->tldepth);
|
whcst.min_seq, whcst.max_seq, whc->max_drop_seq, whc->hdepth, whc->tldepth);
|
||||||
}
|
}
|
||||||
|
@ -1128,7 +1184,7 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
|
||||||
assert (whc->seq_size == 0 || seq > whc->maxseq_node->seq);
|
assert (whc->seq_size == 0 || seq > whc->maxseq_node->seq);
|
||||||
|
|
||||||
/* Always insert in seq admin */
|
/* Always insert in seq admin */
|
||||||
newn = whc_default_insert_seq (whc, max_drop_seq, seq, plist, serdata);
|
newn = whc_default_insert_seq (whc, max_drop_seq, seq, exp, plist, serdata);
|
||||||
|
|
||||||
TRACE (" whcn %p:", (void*)newn);
|
TRACE (" whcn %p:", (void*)newn);
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "dds/ddsi/ddsi_serdata.h"
|
#include "dds/ddsi/ddsi_serdata.h"
|
||||||
#include "dds/ddsi/q_unused.h"
|
#include "dds/ddsi/q_unused.h"
|
||||||
#include "dds/ddsi/q_config.h"
|
#include "dds/ddsi/q_config.h"
|
||||||
#include "dds/ddsi/q_ephash.h"
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
#include "dds/ddsi/q_globals.h"
|
#include "dds/ddsi/q_globals.h"
|
||||||
#include "dds/ddsi/ddsi_tkmap.h"
|
#include "dds/ddsi/ddsi_tkmap.h"
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
struct bwhc {
|
struct bwhc {
|
||||||
struct whc common;
|
struct whc common;
|
||||||
enum ddsi_sertopic_builtintopic_type type;
|
enum ddsi_sertopic_builtintopic_type type;
|
||||||
const struct ephash *guid_hash;
|
const struct entity_index *entidx;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum bwhc_iter_state {
|
enum bwhc_iter_state {
|
||||||
|
@ -42,7 +42,7 @@ struct bwhc_iter {
|
||||||
struct whc_sample_iter_base c;
|
struct whc_sample_iter_base c;
|
||||||
enum bwhc_iter_state st;
|
enum bwhc_iter_state st;
|
||||||
bool have_sample;
|
bool have_sample;
|
||||||
struct ephash_enum it;
|
struct entidx_enum it;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* check that our definition of whc_sample_iter fits in the type that callers allocate */
|
/* check that our definition of whc_sample_iter fits in the type that callers allocate */
|
||||||
|
@ -92,11 +92,11 @@ static bool bwhc_sample_iter_borrow_next (struct whc_sample_iter *opaque_it, str
|
||||||
case DSBT_READER: kind = EK_READER; break;
|
case DSBT_READER: kind = EK_READER; break;
|
||||||
}
|
}
|
||||||
assert (whc->type == DSBT_PARTICIPANT || kind != EK_PARTICIPANT);
|
assert (whc->type == DSBT_PARTICIPANT || kind != EK_PARTICIPANT);
|
||||||
ephash_enum_init (&it->it, whc->guid_hash, kind);
|
entidx_enum_init (&it->it, whc->entidx, kind);
|
||||||
it->st = BIS_LOCAL;
|
it->st = BIS_LOCAL;
|
||||||
/* FALLS THROUGH */
|
/* FALLS THROUGH */
|
||||||
case BIS_LOCAL:
|
case BIS_LOCAL:
|
||||||
while ((entity = ephash_enum_next (&it->it)) != NULL)
|
while ((entity = entidx_enum_next (&it->it)) != NULL)
|
||||||
if (is_visible (entity))
|
if (is_visible (entity))
|
||||||
break;
|
break;
|
||||||
if (entity) {
|
if (entity) {
|
||||||
|
@ -104,7 +104,7 @@ static bool bwhc_sample_iter_borrow_next (struct whc_sample_iter *opaque_it, str
|
||||||
it->have_sample = true;
|
it->have_sample = true;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
ephash_enum_fini (&it->it);
|
entidx_enum_fini (&it->it);
|
||||||
it->st = BIS_INIT_PROXY;
|
it->st = BIS_INIT_PROXY;
|
||||||
}
|
}
|
||||||
/* FALLS THROUGH */
|
/* FALLS THROUGH */
|
||||||
|
@ -115,11 +115,11 @@ static bool bwhc_sample_iter_borrow_next (struct whc_sample_iter *opaque_it, str
|
||||||
case DSBT_READER: kind = EK_PROXY_READER; break;
|
case DSBT_READER: kind = EK_PROXY_READER; break;
|
||||||
}
|
}
|
||||||
assert (kind != EK_PARTICIPANT);
|
assert (kind != EK_PARTICIPANT);
|
||||||
ephash_enum_init (&it->it, whc->guid_hash, kind);
|
entidx_enum_init (&it->it, whc->entidx, kind);
|
||||||
it->st = BIS_PROXY;
|
it->st = BIS_PROXY;
|
||||||
/* FALLS THROUGH */
|
/* FALLS THROUGH */
|
||||||
case BIS_PROXY:
|
case BIS_PROXY:
|
||||||
while ((entity = ephash_enum_next (&it->it)) != NULL)
|
while ((entity = entidx_enum_next (&it->it)) != NULL)
|
||||||
if (is_visible (entity))
|
if (is_visible (entity))
|
||||||
break;
|
break;
|
||||||
if (entity) {
|
if (entity) {
|
||||||
|
@ -127,7 +127,7 @@ static bool bwhc_sample_iter_borrow_next (struct whc_sample_iter *opaque_it, str
|
||||||
it->have_sample = true;
|
it->have_sample = true;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
ephash_enum_fini (&it->it);
|
entidx_enum_fini (&it->it);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,11 +143,12 @@ static void bwhc_get_state (const struct whc *whc, struct whc_state *st)
|
||||||
st->unacked_bytes = 0;
|
st->unacked_bytes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bwhc_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk)
|
static int bwhc_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, nn_mtime_t exp, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk)
|
||||||
{
|
{
|
||||||
(void)whc;
|
(void)whc;
|
||||||
(void)max_drop_seq;
|
(void)max_drop_seq;
|
||||||
(void)seq;
|
(void)seq;
|
||||||
|
(void)exp;
|
||||||
(void)serdata;
|
(void)serdata;
|
||||||
(void)tk;
|
(void)tk;
|
||||||
if (plist)
|
if (plist)
|
||||||
|
@ -192,11 +193,11 @@ static const struct whc_ops bwhc_ops = {
|
||||||
.free = bwhc_free
|
.free = bwhc_free
|
||||||
};
|
};
|
||||||
|
|
||||||
struct whc *builtintopic_whc_new (enum ddsi_sertopic_builtintopic_type type, const struct ephash *guid_hash)
|
struct whc *builtintopic_whc_new (enum ddsi_sertopic_builtintopic_type type, const struct entity_index *entidx)
|
||||||
{
|
{
|
||||||
struct bwhc *whc = ddsrt_malloc (sizeof (*whc));
|
struct bwhc *whc = ddsrt_malloc (sizeof (*whc));
|
||||||
whc->common.ops = &bwhc_ops;
|
whc->common.ops = &bwhc_ops;
|
||||||
whc->type = type;
|
whc->type = type;
|
||||||
whc->guid_hash = guid_hash;
|
whc->entidx = entidx;
|
||||||
return (struct whc *) whc;
|
return (struct whc *) whc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "dds/ddsi/ddsi_serdata.h"
|
#include "dds/ddsi/ddsi_serdata.h"
|
||||||
#include "dds__stream.h"
|
#include "dds__stream.h"
|
||||||
#include "dds/ddsi/q_transmit.h"
|
#include "dds/ddsi/q_transmit.h"
|
||||||
#include "dds/ddsi/q_ephash.h"
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/ddsi/q_config.h"
|
#include "dds/ddsi/q_config.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
#include "dds/ddsi/q_radmin.h"
|
#include "dds/ddsi/q_radmin.h"
|
||||||
|
@ -99,7 +99,7 @@ static dds_return_t deliver_locally (struct writer *wr, struct ddsi_serdata *pay
|
||||||
{
|
{
|
||||||
dds_duration_t max_block_ms = wr->xqos->reliability.max_blocking_time;
|
dds_duration_t max_block_ms = wr->xqos->reliability.max_blocking_time;
|
||||||
struct ddsi_writer_info pwr_info;
|
struct ddsi_writer_info pwr_info;
|
||||||
ddsi_make_writer_info (&pwr_info, &wr->e, wr->xqos);
|
ddsi_make_writer_info (&pwr_info, &wr->e, wr->xqos, payload->statusinfo);
|
||||||
for (uint32_t i = 0; rdary[i]; i++) {
|
for (uint32_t i = 0; rdary[i]; i++) {
|
||||||
DDS_CTRACE (&wr->e.gv->logconfig, "reader "PGUIDFMT"\n", PGUID (rdary[i]->e.guid));
|
DDS_CTRACE (&wr->e.gv->logconfig, "reader "PGUIDFMT"\n", PGUID (rdary[i]->e.guid));
|
||||||
if ((ret = try_store (rdary[i]->rhc, &pwr_info, payload, tk, &max_block_ms)) != DDS_RETCODE_OK)
|
if ((ret = try_store (rdary[i]->rhc, &pwr_info, payload, tk, &max_block_ms)) != DDS_RETCODE_OK)
|
||||||
|
@ -121,15 +121,15 @@ static dds_return_t deliver_locally (struct writer *wr, struct ddsi_serdata *pay
|
||||||
ddsrt_avl_iter_t it;
|
ddsrt_avl_iter_t it;
|
||||||
struct pwr_rd_match *m;
|
struct pwr_rd_match *m;
|
||||||
struct ddsi_writer_info wrinfo;
|
struct ddsi_writer_info wrinfo;
|
||||||
const struct ephash *gh = wr->e.gv->guid_hash;
|
const struct entity_index *gh = wr->e.gv->entity_index;
|
||||||
dds_duration_t max_block_ms = wr->xqos->reliability.max_blocking_time;
|
dds_duration_t max_block_ms = wr->xqos->reliability.max_blocking_time;
|
||||||
ddsrt_mutex_unlock (&wr->rdary.rdary_lock);
|
ddsrt_mutex_unlock (&wr->rdary.rdary_lock);
|
||||||
ddsi_make_writer_info (&wrinfo, &wr->e, wr->xqos);
|
ddsi_make_writer_info (&wrinfo, &wr->e, wr->xqos, payload->statusinfo);
|
||||||
ddsrt_mutex_lock (&wr->e.lock);
|
ddsrt_mutex_lock (&wr->e.lock);
|
||||||
for (m = ddsrt_avl_iter_first (&wr_local_readers_treedef, &wr->local_readers, &it); m != NULL; m = ddsrt_avl_iter_next (&it))
|
for (m = ddsrt_avl_iter_first (&wr_local_readers_treedef, &wr->local_readers, &it); m != NULL; m = ddsrt_avl_iter_next (&it))
|
||||||
{
|
{
|
||||||
struct reader *rd;
|
struct reader *rd;
|
||||||
if ((rd = ephash_lookup_reader_guid (gh, &m->rd_guid)) != NULL)
|
if ((rd = entidx_lookup_reader_guid (gh, &m->rd_guid)) != NULL)
|
||||||
{
|
{
|
||||||
DDS_CTRACE (&wr->e.gv->logconfig, "reader-via-guid "PGUIDFMT"\n", PGUID (rd->e.guid));
|
DDS_CTRACE (&wr->e.gv->logconfig, "reader-via-guid "PGUIDFMT"\n", PGUID (rd->e.guid));
|
||||||
/* Copied the return value ignore from DDSI deliver_user_data () function. */
|
/* Copied the return value ignore from DDSI deliver_user_data () function. */
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
#include "dds/ddsi/q_thread.h"
|
#include "dds/ddsi/q_thread.h"
|
||||||
#include "dds/ddsi/q_xmsg.h"
|
#include "dds/ddsi/q_xmsg.h"
|
||||||
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds__writer.h"
|
#include "dds__writer.h"
|
||||||
#include "dds__listener.h"
|
#include "dds__listener.h"
|
||||||
#include "dds__init.h"
|
#include "dds__init.h"
|
||||||
|
@ -217,14 +218,28 @@ static dds_return_t dds_writer_delete (dds_entity *e)
|
||||||
return DDS_RETCODE_OK;
|
return DDS_RETCODE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static dds_return_t validate_writer_qos (const dds_qos_t *wqos)
|
||||||
|
{
|
||||||
|
#ifndef DDSI_INCLUDE_LIFESPAN
|
||||||
|
if (wqos != NULL && (wqos->present & QP_LIFESPAN) && wqos->lifespan.duration != DDS_INFINITY)
|
||||||
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
|
#else
|
||||||
|
DDSRT_UNUSED_ARG (wqos);
|
||||||
|
#endif
|
||||||
|
return DDS_RETCODE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static dds_return_t dds_writer_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled)
|
static dds_return_t dds_writer_qos_set (dds_entity *e, const dds_qos_t *qos, bool enabled)
|
||||||
{
|
{
|
||||||
/* note: e->m_qos is still the old one to allow for failure here */
|
/* note: e->m_qos is still the old one to allow for failure here */
|
||||||
|
dds_return_t ret;
|
||||||
|
if ((ret = validate_writer_qos(qos)) != DDS_RETCODE_OK)
|
||||||
|
return ret;
|
||||||
if (enabled)
|
if (enabled)
|
||||||
{
|
{
|
||||||
struct writer *wr;
|
struct writer *wr;
|
||||||
thread_state_awake (lookup_thread_state (), &e->m_domain->gv);
|
thread_state_awake (lookup_thread_state (), &e->m_domain->gv);
|
||||||
if ((wr = ephash_lookup_writer_guid (e->m_domain->gv.guid_hash, &e->m_guid)) != NULL)
|
if ((wr = entidx_lookup_writer_guid (e->m_domain->gv.entity_index, &e->m_guid)) != NULL)
|
||||||
update_writer_qos (wr, qos);
|
update_writer_qos (wr, qos);
|
||||||
thread_state_asleep (lookup_thread_state ());
|
thread_state_asleep (lookup_thread_state ());
|
||||||
}
|
}
|
||||||
|
@ -319,7 +334,8 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit
|
||||||
nn_xqos_mergein_missing (wqos, tp->m_entity.m_qos, ~(uint64_t)0);
|
nn_xqos_mergein_missing (wqos, tp->m_entity.m_qos, ~(uint64_t)0);
|
||||||
nn_xqos_mergein_missing (wqos, &pub->m_entity.m_domain->gv.default_xqos_wr, ~(uint64_t)0);
|
nn_xqos_mergein_missing (wqos, &pub->m_entity.m_domain->gv.default_xqos_wr, ~(uint64_t)0);
|
||||||
|
|
||||||
if ((rc = nn_xqos_valid (&pub->m_entity.m_domain->gv.logconfig, wqos)) < 0)
|
if ((rc = nn_xqos_valid (&pub->m_entity.m_domain->gv.logconfig, wqos)) < 0 ||
|
||||||
|
(rc = validate_writer_qos(wqos)) != DDS_RETCODE_OK)
|
||||||
{
|
{
|
||||||
dds_delete_qos(wqos);
|
dds_delete_qos(wqos);
|
||||||
goto err_bad_qos;
|
goto err_bad_qos;
|
||||||
|
|
|
@ -14,6 +14,7 @@ include(CUnit)
|
||||||
idlc_generate(RoundTrip RoundTrip.idl)
|
idlc_generate(RoundTrip RoundTrip.idl)
|
||||||
idlc_generate(Space Space.idl)
|
idlc_generate(Space Space.idl)
|
||||||
idlc_generate(TypesArrayKey TypesArrayKey.idl)
|
idlc_generate(TypesArrayKey TypesArrayKey.idl)
|
||||||
|
idlc_generate(WriteTypes WriteTypes.idl)
|
||||||
|
|
||||||
set(ddsc_test_sources
|
set(ddsc_test_sources
|
||||||
"basic.c"
|
"basic.c"
|
||||||
|
@ -51,15 +52,20 @@ set(ddsc_test_sources
|
||||||
"waitset.c"
|
"waitset.c"
|
||||||
"waitset_torture.c"
|
"waitset_torture.c"
|
||||||
"write.c"
|
"write.c"
|
||||||
|
"write_various_types.c"
|
||||||
"writer.c")
|
"writer.c")
|
||||||
|
|
||||||
|
if(ENABLE_LIFESPAN)
|
||||||
|
list(APPEND ddsc_test_sources "lifespan.c")
|
||||||
|
endif()
|
||||||
|
|
||||||
add_cunit_executable(cunit_ddsc ${ddsc_test_sources})
|
add_cunit_executable(cunit_ddsc ${ddsc_test_sources})
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
cunit_ddsc PRIVATE
|
cunit_ddsc PRIVATE
|
||||||
"$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/src/include/>"
|
"$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/src/include/>"
|
||||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../../ddsc/src>"
|
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../../ddsc/src>"
|
||||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../../ddsi/include>")
|
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../../ddsi/include>")
|
||||||
target_link_libraries(cunit_ddsc PRIVATE RoundTrip Space TypesArrayKey ddsc)
|
target_link_libraries(cunit_ddsc PRIVATE RoundTrip Space TypesArrayKey WriteTypes ddsc)
|
||||||
|
|
||||||
# Setup environment for config-tests
|
# Setup environment for config-tests
|
||||||
get_test_property(CUnit_ddsc_config_simple_udp ENVIRONMENT CUnit_ddsc_config_simple_udp_env)
|
get_test_property(CUnit_ddsc_config_simple_udp ENVIRONMENT CUnit_ddsc_config_simple_udp_env)
|
||||||
|
|
25
src/core/ddsc/tests/WriteTypes.idl
Normal file
25
src/core/ddsc/tests/WriteTypes.idl
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
module WriteTypes {
|
||||||
|
struct a {
|
||||||
|
octet k[3];
|
||||||
|
unsigned long long ll;
|
||||||
|
};
|
||||||
|
#pragma keylist a k
|
||||||
|
|
||||||
|
struct b {
|
||||||
|
unsigned short k[3];
|
||||||
|
unsigned long long ll;
|
||||||
|
};
|
||||||
|
#pragma keylist b k
|
||||||
|
|
||||||
|
struct c {
|
||||||
|
unsigned long k[3];
|
||||||
|
unsigned long long ll;
|
||||||
|
};
|
||||||
|
#pragma keylist c k
|
||||||
|
|
||||||
|
struct d {
|
||||||
|
unsigned long long k[3];
|
||||||
|
unsigned long long ll;
|
||||||
|
};
|
||||||
|
#pragma keylist d k
|
||||||
|
};
|
164
src/core/ddsc/tests/lifespan.c
Normal file
164
src/core/ddsc/tests/lifespan.c
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
/*
|
||||||
|
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||||
|
* v. 1.0 which is available at
|
||||||
|
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||||
|
*/
|
||||||
|
#include <assert.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include "dds/dds.h"
|
||||||
|
#include "CUnit/Theory.h"
|
||||||
|
#include "Space.h"
|
||||||
|
|
||||||
|
#include "dds/ddsrt/process.h"
|
||||||
|
#include "dds/ddsrt/threads.h"
|
||||||
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
|
#include "dds/ddsi/q_entity.h"
|
||||||
|
#include "dds/ddsi/q_whc.h"
|
||||||
|
#include "dds__entity.h"
|
||||||
|
|
||||||
|
static dds_entity_t g_participant = 0;
|
||||||
|
static dds_entity_t g_subscriber = 0;
|
||||||
|
static dds_entity_t g_publisher = 0;
|
||||||
|
static dds_entity_t g_topic = 0;
|
||||||
|
static dds_entity_t g_reader = 0;
|
||||||
|
static dds_entity_t g_writer = 0;
|
||||||
|
static dds_entity_t g_waitset = 0;
|
||||||
|
static dds_entity_t g_rcond = 0;
|
||||||
|
static dds_entity_t g_qcond = 0;
|
||||||
|
|
||||||
|
static char*
|
||||||
|
create_topic_name(const char *prefix, char *name, size_t size)
|
||||||
|
{
|
||||||
|
/* Get semi random g_topic name. */
|
||||||
|
ddsrt_pid_t pid = ddsrt_getpid();
|
||||||
|
ddsrt_tid_t tid = ddsrt_gettid();
|
||||||
|
(void) snprintf(name, size, "%s_pid%"PRIdPID"_tid%"PRIdTID"", prefix, pid, tid);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lifespan_init(void)
|
||||||
|
{
|
||||||
|
dds_attach_t triggered;
|
||||||
|
dds_return_t ret;
|
||||||
|
char name[100];
|
||||||
|
dds_qos_t *qos;
|
||||||
|
|
||||||
|
qos = dds_create_qos();
|
||||||
|
CU_ASSERT_PTR_NOT_NULL_FATAL(qos);
|
||||||
|
|
||||||
|
g_participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||||
|
CU_ASSERT_FATAL(g_participant > 0);
|
||||||
|
|
||||||
|
g_subscriber = dds_create_subscriber(g_participant, NULL, NULL);
|
||||||
|
CU_ASSERT_FATAL(g_subscriber > 0);
|
||||||
|
|
||||||
|
g_publisher = dds_create_publisher(g_participant, NULL, NULL);
|
||||||
|
CU_ASSERT_FATAL(g_publisher > 0);
|
||||||
|
|
||||||
|
g_waitset = dds_create_waitset(g_participant);
|
||||||
|
CU_ASSERT_FATAL(g_waitset > 0);
|
||||||
|
|
||||||
|
g_topic = dds_create_topic(g_participant, &Space_Type1_desc, create_topic_name("ddsc_qos_lifespan_test", name, sizeof name), NULL, NULL);
|
||||||
|
CU_ASSERT_FATAL(g_topic > 0);
|
||||||
|
|
||||||
|
dds_qset_history(qos, DDS_HISTORY_KEEP_ALL, DDS_LENGTH_UNLIMITED);
|
||||||
|
dds_qset_durability(qos, DDS_DURABILITY_TRANSIENT_LOCAL);
|
||||||
|
dds_qset_reliability(qos, DDS_RELIABILITY_RELIABLE, DDS_INFINITY);
|
||||||
|
g_writer = dds_create_writer(g_publisher, g_topic, qos, NULL);
|
||||||
|
CU_ASSERT_FATAL(g_writer > 0);
|
||||||
|
g_reader = dds_create_reader(g_subscriber, g_topic, qos, NULL);
|
||||||
|
CU_ASSERT_FATAL(g_reader > 0);
|
||||||
|
|
||||||
|
/* Sync g_reader to g_writer. */
|
||||||
|
ret = dds_set_status_mask(g_reader, DDS_SUBSCRIPTION_MATCHED_STATUS);
|
||||||
|
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
|
||||||
|
ret = dds_waitset_attach(g_waitset, g_reader, g_reader);
|
||||||
|
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
|
||||||
|
ret = dds_waitset_wait(g_waitset, &triggered, 1, DDS_SECS(1));
|
||||||
|
CU_ASSERT_EQUAL_FATAL(ret, 1);
|
||||||
|
CU_ASSERT_EQUAL_FATAL(g_reader, (dds_entity_t)(intptr_t)triggered);
|
||||||
|
ret = dds_waitset_detach(g_waitset, g_reader);
|
||||||
|
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
|
||||||
|
|
||||||
|
/* Sync g_writer to g_reader. */
|
||||||
|
ret = dds_set_status_mask(g_writer, DDS_PUBLICATION_MATCHED_STATUS);
|
||||||
|
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
|
||||||
|
ret = dds_waitset_attach(g_waitset, g_writer, g_writer);
|
||||||
|
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
|
||||||
|
ret = dds_waitset_wait(g_waitset, &triggered, 1, DDS_SECS(1));
|
||||||
|
CU_ASSERT_EQUAL_FATAL(ret, 1);
|
||||||
|
CU_ASSERT_EQUAL_FATAL(g_writer, (dds_entity_t)(intptr_t)triggered);
|
||||||
|
ret = dds_waitset_detach(g_waitset, g_writer);
|
||||||
|
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
|
||||||
|
|
||||||
|
dds_delete_qos(qos);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lifespan_fini(void)
|
||||||
|
{
|
||||||
|
dds_delete(g_rcond);
|
||||||
|
dds_delete(g_qcond);
|
||||||
|
dds_delete(g_reader);
|
||||||
|
dds_delete(g_writer);
|
||||||
|
dds_delete(g_subscriber);
|
||||||
|
dds_delete(g_publisher);
|
||||||
|
dds_delete(g_waitset);
|
||||||
|
dds_delete(g_topic);
|
||||||
|
dds_delete(g_participant);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void check_whc_state(dds_entity_t writer, seqno_t exp_min, seqno_t exp_max)
|
||||||
|
{
|
||||||
|
struct dds_entity *wr_entity;
|
||||||
|
struct writer *wr;
|
||||||
|
struct whc_state whcst;
|
||||||
|
CU_ASSERT_EQUAL_FATAL(dds_entity_pin(writer, &wr_entity), 0);
|
||||||
|
thread_state_awake(lookup_thread_state(), &wr_entity->m_domain->gv);
|
||||||
|
wr = entidx_lookup_writer_guid(wr_entity->m_domain->gv.entity_index, &wr_entity->m_guid);
|
||||||
|
CU_ASSERT_FATAL(wr != NULL);
|
||||||
|
assert(wr != NULL); /* for Clang's static analyzer */
|
||||||
|
whc_get_state(wr->whc, &whcst);
|
||||||
|
thread_state_asleep(lookup_thread_state());
|
||||||
|
dds_entity_unpin(wr_entity);
|
||||||
|
|
||||||
|
CU_ASSERT_EQUAL_FATAL (whcst.min_seq, exp_min);
|
||||||
|
CU_ASSERT_EQUAL_FATAL (whcst.max_seq, exp_max);
|
||||||
|
}
|
||||||
|
|
||||||
|
CU_Test(ddsc_lifespan, basic, .init=lifespan_init, .fini=lifespan_fini)
|
||||||
|
{
|
||||||
|
Space_Type1 sample = { 0, 0, 0 };
|
||||||
|
dds_return_t ret;
|
||||||
|
dds_duration_t exp = DDS_MSECS(500);
|
||||||
|
dds_qos_t *qos;
|
||||||
|
|
||||||
|
qos = dds_create_qos();
|
||||||
|
CU_ASSERT_PTR_NOT_NULL_FATAL(qos);
|
||||||
|
|
||||||
|
/* Write with default qos: lifespan inifinite */
|
||||||
|
ret = dds_write (g_writer, &sample);
|
||||||
|
CU_ASSERT_EQUAL_FATAL (ret, DDS_RETCODE_OK);
|
||||||
|
check_whc_state(g_writer, 1, 1);
|
||||||
|
|
||||||
|
dds_sleepfor (2 * exp);
|
||||||
|
check_whc_state(g_writer, 1, 1);
|
||||||
|
|
||||||
|
dds_qset_lifespan(qos, exp);
|
||||||
|
ret = dds_set_qos(g_writer, qos);
|
||||||
|
CU_ASSERT_EQUAL_FATAL (ret, DDS_RETCODE_OK);
|
||||||
|
ret = dds_write (g_writer, &sample);
|
||||||
|
CU_ASSERT_EQUAL_FATAL (ret, DDS_RETCODE_OK);
|
||||||
|
check_whc_state(g_writer, 2, 2);
|
||||||
|
|
||||||
|
dds_sleepfor (2 * exp);
|
||||||
|
check_whc_state(g_writer, -1, -1);
|
||||||
|
|
||||||
|
dds_delete_qos(qos);
|
||||||
|
}
|
|
@ -20,6 +20,7 @@
|
||||||
#include "dds/version.h"
|
#include "dds/version.h"
|
||||||
#include "dds__entity.h"
|
#include "dds__entity.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/ddsrt/cdtors.h"
|
#include "dds/ddsrt/cdtors.h"
|
||||||
#include "dds/ddsrt/misc.h"
|
#include "dds/ddsrt/misc.h"
|
||||||
#include "dds/ddsrt/process.h"
|
#include "dds/ddsrt/process.h"
|
||||||
|
@ -97,7 +98,7 @@ static seqno_t get_pmd_seqno(dds_entity_t participant)
|
||||||
struct writer *wr;
|
struct writer *wr;
|
||||||
CU_ASSERT_EQUAL_FATAL(dds_entity_pin(participant, &pp_entity), 0);
|
CU_ASSERT_EQUAL_FATAL(dds_entity_pin(participant, &pp_entity), 0);
|
||||||
thread_state_awake(lookup_thread_state(), &pp_entity->m_domain->gv);
|
thread_state_awake(lookup_thread_state(), &pp_entity->m_domain->gv);
|
||||||
pp = ephash_lookup_participant_guid(pp_entity->m_domain->gv.guid_hash, &pp_entity->m_guid);
|
pp = entidx_lookup_participant_guid(pp_entity->m_domain->gv.entity_index, &pp_entity->m_guid);
|
||||||
wr = get_builtin_writer(pp, NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER);
|
wr = get_builtin_writer(pp, NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER);
|
||||||
CU_ASSERT_FATAL(wr != NULL);
|
CU_ASSERT_FATAL(wr != NULL);
|
||||||
assert(wr != NULL); /* for Clang's static analyzer */
|
assert(wr != NULL); /* for Clang's static analyzer */
|
||||||
|
@ -117,7 +118,7 @@ static dds_duration_t get_pmd_interval(dds_entity_t participant)
|
||||||
struct participant *pp;
|
struct participant *pp;
|
||||||
CU_ASSERT_EQUAL_FATAL(dds_entity_pin(participant, &pp_entity), 0);
|
CU_ASSERT_EQUAL_FATAL(dds_entity_pin(participant, &pp_entity), 0);
|
||||||
thread_state_awake(lookup_thread_state(), &pp_entity->m_domain->gv);
|
thread_state_awake(lookup_thread_state(), &pp_entity->m_domain->gv);
|
||||||
pp = ephash_lookup_participant_guid(pp_entity->m_domain->gv.guid_hash, &pp_entity->m_guid);
|
pp = entidx_lookup_participant_guid(pp_entity->m_domain->gv.entity_index, &pp_entity->m_guid);
|
||||||
intv = pp_get_pmd_interval(pp);
|
intv = pp_get_pmd_interval(pp);
|
||||||
thread_state_asleep(lookup_thread_state());
|
thread_state_asleep(lookup_thread_state());
|
||||||
dds_entity_unpin(pp_entity);
|
dds_entity_unpin(pp_entity);
|
||||||
|
|
249
src/core/ddsc/tests/write_various_types.c
Normal file
249
src/core/ddsc/tests/write_various_types.c
Normal file
|
@ -0,0 +1,249 @@
|
||||||
|
/*
|
||||||
|
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||||
|
* v. 1.0 which is available at
|
||||||
|
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||||
|
*/
|
||||||
|
#include <assert.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include "dds/dds.h"
|
||||||
|
#include "CUnit/Theory.h"
|
||||||
|
#include "WriteTypes.h"
|
||||||
|
|
||||||
|
#include "dds/ddsrt/process.h"
|
||||||
|
#include "dds/ddsrt/threads.h"
|
||||||
|
#include "dds/ddsrt/environ.h"
|
||||||
|
|
||||||
|
#define DDS_DOMAINID_PUB 0
|
||||||
|
#define DDS_DOMAINID_SUB 1
|
||||||
|
#define DDS_CONFIG_NO_PORT_GAIN "${CYCLONEDDS_URI}${CYCLONEDDS_URI:+,}<Discovery><ExternalDomainId>0</ExternalDomainId></Discovery>"
|
||||||
|
#define DDS_CONFIG_NO_PORT_GAIN_LOG "${CYCLONEDDS_URI}${CYCLONEDDS_URI:+,}<Tracing><OutputFile>cyclonedds_writetypes_various.${CYCLONEDDS_DOMAIN_ID}.${CYCLONEDDS_PID}.log</OutputFile><Verbosity>finest</Verbosity></Tracing><Discovery><ExternalDomainId>0</ExternalDomainId></Discovery>"
|
||||||
|
|
||||||
|
static uint32_t g_topic_nr = 0;
|
||||||
|
static dds_entity_t g_pub_domain = 0;
|
||||||
|
static dds_entity_t g_pub_participant = 0;
|
||||||
|
static dds_entity_t g_pub_publisher = 0;
|
||||||
|
|
||||||
|
static dds_entity_t g_sub_domain = 0;
|
||||||
|
static dds_entity_t g_sub_participant = 0;
|
||||||
|
static dds_entity_t g_sub_subscriber = 0;
|
||||||
|
|
||||||
|
static char *create_topic_name (const char *prefix, uint32_t nr, char *name, size_t size)
|
||||||
|
{
|
||||||
|
/* Get unique g_topic name. */
|
||||||
|
ddsrt_pid_t pid = ddsrt_getpid ();
|
||||||
|
ddsrt_tid_t tid = ddsrt_gettid ();
|
||||||
|
(void) snprintf (name, size, "%s%d_pid%" PRIdPID "_tid%" PRIdTID "", prefix, nr, pid, tid);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void writetypes_init(void)
|
||||||
|
{
|
||||||
|
/* Domains for pub and sub use a different domain id, but the portgain setting
|
||||||
|
* in configuration is 0, so that both domains will map to the same port number.
|
||||||
|
* This allows to create two domains in a single test process. */
|
||||||
|
char *conf_pub = ddsrt_expand_envvars (DDS_CONFIG_NO_PORT_GAIN, DDS_DOMAINID_PUB);
|
||||||
|
char *conf_sub = ddsrt_expand_envvars (DDS_CONFIG_NO_PORT_GAIN, DDS_DOMAINID_SUB);
|
||||||
|
g_pub_domain = dds_create_domain (DDS_DOMAINID_PUB, conf_pub);
|
||||||
|
g_sub_domain = dds_create_domain (DDS_DOMAINID_SUB, conf_sub);
|
||||||
|
dds_free (conf_pub);
|
||||||
|
dds_free (conf_sub);
|
||||||
|
|
||||||
|
g_pub_participant = dds_create_participant (DDS_DOMAINID_PUB, NULL, NULL);
|
||||||
|
CU_ASSERT_FATAL (g_pub_participant > 0);
|
||||||
|
g_sub_participant = dds_create_participant (DDS_DOMAINID_SUB, NULL, NULL);
|
||||||
|
CU_ASSERT_FATAL (g_sub_participant > 0);
|
||||||
|
|
||||||
|
g_pub_publisher = dds_create_publisher (g_pub_participant, NULL, NULL);
|
||||||
|
CU_ASSERT_FATAL (g_pub_publisher > 0);
|
||||||
|
g_sub_subscriber = dds_create_subscriber (g_sub_participant, NULL, NULL);
|
||||||
|
CU_ASSERT_FATAL (g_sub_subscriber > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void writetypes_fini (void)
|
||||||
|
{
|
||||||
|
dds_delete (g_sub_subscriber);
|
||||||
|
dds_delete (g_pub_publisher);
|
||||||
|
dds_delete (g_sub_participant);
|
||||||
|
dds_delete (g_pub_participant);
|
||||||
|
dds_delete (g_sub_domain);
|
||||||
|
dds_delete (g_pub_domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef bool (*compare_fn_t) (const void *a, const void *b);
|
||||||
|
|
||||||
|
#define ABCD_CMP(typ_) \
|
||||||
|
static bool typ_##_cmp (const void *va, const void *vb) \
|
||||||
|
{ \
|
||||||
|
const struct WriteTypes_##typ_ *a = va; \
|
||||||
|
const struct WriteTypes_##typ_ *b = vb; \
|
||||||
|
return a->k[0] == b->k[0] && a->k[1] == b->k[1] && a->k[2] == b->k[2] && a->ll == b->ll; \
|
||||||
|
}
|
||||||
|
ABCD_CMP (a)
|
||||||
|
ABCD_CMP (b)
|
||||||
|
ABCD_CMP (c)
|
||||||
|
ABCD_CMP (d)
|
||||||
|
#undef ABCD_CMP
|
||||||
|
|
||||||
|
struct sample {
|
||||||
|
bool in_result;
|
||||||
|
const void *data;
|
||||||
|
};
|
||||||
|
#define S(n) &(struct WriteTypes_##n)
|
||||||
|
static const struct sample a_samples[] = {
|
||||||
|
{ 1, S(a) { .k={1,2,3}, .ll = UINT64_C (0x1234567890abcdef) } },
|
||||||
|
{ 0, S(a) { .k={3,2,1}, .ll = UINT64_C (0) } },
|
||||||
|
{ 1, S(a) { .k={3,2,1}, .ll = UINT64_C (1) } },
|
||||||
|
};
|
||||||
|
static const struct sample b_samples[] = {
|
||||||
|
{ 1, S(b) { .k={1001,1002,1003}, .ll = UINT64_C (0x1234567890abcdef) } },
|
||||||
|
{ 0, S(b) { .k={1003,1002,1001}, .ll = UINT64_C (0) } },
|
||||||
|
{ 1, S(b) { .k={1003,1002,1001}, .ll = UINT64_C (1) } },
|
||||||
|
};
|
||||||
|
static const struct sample c_samples[] = {
|
||||||
|
{ 1, S(c) { .k={12340001,12340002,12340003}, .ll = UINT64_C (0x1234567890abcdef) } },
|
||||||
|
{ 0, S(c) { .k={12340003,12340002,12340001}, .ll = UINT64_C (0) } },
|
||||||
|
{ 1, S(c) { .k={12340003,12340002,12340001}, .ll = UINT64_C (1) } },
|
||||||
|
};
|
||||||
|
static const struct sample d_samples[] = {
|
||||||
|
{ 1, S(d) { .k={123400056780001,2,3}, .ll = UINT64_C (0x1234567890abcdef) } },
|
||||||
|
{ 0, S(d) { .k={123400056780003,2,1}, .ll = UINT64_C (0) } },
|
||||||
|
{ 1, S(d) { .k={123400056780003,2,1}, .ll = UINT64_C (1) } },
|
||||||
|
};
|
||||||
|
#undef S
|
||||||
|
|
||||||
|
#define T(n) &WriteTypes_##n##_desc
|
||||||
|
#define C(n) &n##_cmp
|
||||||
|
#define N(n) (sizeof (n##_samples) / sizeof (n##_samples[0]))
|
||||||
|
#define S(n) n##_samples
|
||||||
|
CU_TheoryDataPoints(ddsc_writetypes, various) = {
|
||||||
|
CU_DataPoints(const dds_topic_descriptor_t *, T(a), T(b), T(c), T(d)),
|
||||||
|
CU_DataPoints(compare_fn_t, C(a), C(b), C(c), C(d)),
|
||||||
|
CU_DataPoints(size_t, N(a), N(b), N(c), N(d)),
|
||||||
|
CU_DataPoints(const struct sample *, S(a), S(b), S(c), S(d)),
|
||||||
|
};
|
||||||
|
#undef S
|
||||||
|
#undef N
|
||||||
|
#undef C
|
||||||
|
#undef T
|
||||||
|
|
||||||
|
#define MAX_SAMPLES 5
|
||||||
|
|
||||||
|
CU_Theory((const dds_topic_descriptor_t *desc, compare_fn_t cmp, size_t nsamples, const struct sample *samples), ddsc_writetypes, various, .init = writetypes_init, .fini = writetypes_fini, .timeout = 10)
|
||||||
|
{
|
||||||
|
dds_entity_t pub_topic;
|
||||||
|
dds_entity_t sub_topic;
|
||||||
|
dds_entity_t reader;
|
||||||
|
dds_entity_t writer;
|
||||||
|
dds_qos_t *qos;
|
||||||
|
dds_return_t rc;
|
||||||
|
char name[100];
|
||||||
|
|
||||||
|
/* nsamples < MAX_SAMPLES so there is room for an invalid sample if we need it */
|
||||||
|
CU_ASSERT_FATAL (nsamples < MAX_SAMPLES);
|
||||||
|
|
||||||
|
qos = dds_create_qos ();
|
||||||
|
CU_ASSERT_FATAL (qos != NULL);
|
||||||
|
dds_qset_reliability (qos, DDS_RELIABILITY_RELIABLE, DDS_SECS (1));
|
||||||
|
dds_qset_writer_data_lifecycle (qos, false);
|
||||||
|
create_topic_name ("ddsc_writetypes_various", g_topic_nr++, name, sizeof name);
|
||||||
|
pub_topic = dds_create_topic (g_pub_participant, desc, name, qos, NULL);
|
||||||
|
CU_ASSERT_FATAL (pub_topic > 0);
|
||||||
|
sub_topic = dds_create_topic (g_sub_participant, desc, name, qos, NULL);
|
||||||
|
CU_ASSERT_FATAL (sub_topic > 0);
|
||||||
|
dds_delete_qos (qos);
|
||||||
|
|
||||||
|
reader = dds_create_reader (g_sub_participant, sub_topic, NULL, NULL);
|
||||||
|
CU_ASSERT_FATAL (reader > 0);
|
||||||
|
writer = dds_create_writer (g_pub_participant, pub_topic, NULL, NULL);
|
||||||
|
CU_ASSERT_FATAL (writer > 0);
|
||||||
|
|
||||||
|
/* simple-minded polling until reader/writer have matched each other */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
dds_publication_matched_status_t st;
|
||||||
|
rc = dds_get_publication_matched_status (writer, &st);
|
||||||
|
CU_ASSERT_FATAL (rc == DDS_RETCODE_OK);
|
||||||
|
if (st.current_count > 0)
|
||||||
|
break;
|
||||||
|
dds_sleepfor (DDS_MSECS (1));
|
||||||
|
}
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
dds_subscription_matched_status_t st;
|
||||||
|
rc = dds_get_subscription_matched_status (reader, &st);
|
||||||
|
CU_ASSERT_FATAL (rc == DDS_RETCODE_OK);
|
||||||
|
if (st.current_count > 0)
|
||||||
|
break;
|
||||||
|
dds_sleepfor (DDS_MSECS (1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write samples */
|
||||||
|
for (size_t i = 0; i < nsamples; i++) {
|
||||||
|
rc = dds_write (writer, samples[i].data);
|
||||||
|
CU_ASSERT_FATAL (rc == DDS_RETCODE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* delete writer, wait until no matching writer: writer lingering should ensure the data
|
||||||
|
has been delivered at that point */
|
||||||
|
rc = dds_delete (writer);
|
||||||
|
CU_ASSERT_FATAL (rc == DDS_RETCODE_OK);
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
dds_subscription_matched_status_t st;
|
||||||
|
rc = dds_get_subscription_matched_status (reader, &st);
|
||||||
|
CU_ASSERT_FATAL (rc == DDS_RETCODE_OK);
|
||||||
|
if (st.current_count == 0)
|
||||||
|
break;
|
||||||
|
dds_sleepfor (DDS_MSECS (1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* instances are unordered; this is a woefully inefficient way of comparing the sets,
|
||||||
|
but for the numbers of samples we do here, it really doesn't matter */
|
||||||
|
dds_sample_info_t si[MAX_SAMPLES];
|
||||||
|
void *xs[MAX_SAMPLES];
|
||||||
|
xs[0] = NULL;
|
||||||
|
int32_t n;
|
||||||
|
n = dds_read (reader, xs, si, MAX_SAMPLES, MAX_SAMPLES);
|
||||||
|
CU_ASSERT_FATAL (n > 0);
|
||||||
|
|
||||||
|
size_t nvalid = 0;
|
||||||
|
for (int32_t j = 0; j < n; j++)
|
||||||
|
{
|
||||||
|
if (si[j].valid_data)
|
||||||
|
nvalid++;
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < nsamples; i++)
|
||||||
|
{
|
||||||
|
if (samples[i].in_result)
|
||||||
|
{
|
||||||
|
/* sample must be present, erase it by marking it invalid */
|
||||||
|
int32_t j;
|
||||||
|
for (j = 0; j < n; j++)
|
||||||
|
if (si[j].valid_data && cmp (samples[i].data, xs[j]))
|
||||||
|
break;
|
||||||
|
CU_ASSERT (j < n);
|
||||||
|
si[j].valid_data = 0;
|
||||||
|
nvalid--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* all valid samples must be accounted for */
|
||||||
|
CU_ASSERT_FATAL (nvalid == 0);
|
||||||
|
|
||||||
|
rc = dds_return_loan (reader, xs, n);
|
||||||
|
CU_ASSERT_FATAL (rc == DDS_RETCODE_OK);
|
||||||
|
|
||||||
|
/* cleanup */
|
||||||
|
rc = dds_delete (reader);
|
||||||
|
CU_ASSERT_FATAL (rc == DDS_RETCODE_OK);
|
||||||
|
rc = dds_delete (sub_topic);
|
||||||
|
CU_ASSERT_FATAL (rc == DDS_RETCODE_OK);
|
||||||
|
rc = dds_delete (pub_topic);
|
||||||
|
CU_ASSERT_FATAL (rc == DDS_RETCODE_OK);
|
||||||
|
}
|
|
@ -30,6 +30,7 @@ PREPEND(srcs_ddsi "${CMAKE_CURRENT_LIST_DIR}/src"
|
||||||
ddsi_threadmon.c
|
ddsi_threadmon.c
|
||||||
ddsi_rhc.c
|
ddsi_rhc.c
|
||||||
ddsi_pmd.c
|
ddsi_pmd.c
|
||||||
|
ddsi_entity_index.c
|
||||||
q_addrset.c
|
q_addrset.c
|
||||||
q_bitset_inlines.c
|
q_bitset_inlines.c
|
||||||
q_bswap.c
|
q_bswap.c
|
||||||
|
@ -37,7 +38,6 @@ PREPEND(srcs_ddsi "${CMAKE_CURRENT_LIST_DIR}/src"
|
||||||
q_ddsi_discovery.c
|
q_ddsi_discovery.c
|
||||||
q_debmon.c
|
q_debmon.c
|
||||||
q_entity.c
|
q_entity.c
|
||||||
q_ephash.c
|
|
||||||
q_gc.c
|
q_gc.c
|
||||||
q_init.c
|
q_init.c
|
||||||
q_lat_estim.c
|
q_lat_estim.c
|
||||||
|
@ -60,6 +60,9 @@ PREPEND(srcs_ddsi "${CMAKE_CURRENT_LIST_DIR}/src"
|
||||||
q_freelist.c
|
q_freelist.c
|
||||||
sysdeps.c
|
sysdeps.c
|
||||||
)
|
)
|
||||||
|
if(ENABLE_LIFESPAN)
|
||||||
|
list(APPEND srcs_ddsi "${CMAKE_CURRENT_LIST_DIR}/src/ddsi_lifespan.c")
|
||||||
|
endif()
|
||||||
|
|
||||||
# The includes should reside close to the code. As long as that's not the case,
|
# The includes should reside close to the code. As long as that's not the case,
|
||||||
# pull them in from this CMakeLists.txt.
|
# pull them in from this CMakeLists.txt.
|
||||||
|
@ -84,6 +87,7 @@ PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/dds/ddsi"
|
||||||
ddsi_builtin_topic_if.h
|
ddsi_builtin_topic_if.h
|
||||||
ddsi_rhc.h
|
ddsi_rhc.h
|
||||||
ddsi_guid.h
|
ddsi_guid.h
|
||||||
|
ddsi_entity_index.h
|
||||||
q_addrset.h
|
q_addrset.h
|
||||||
q_bitset.h
|
q_bitset.h
|
||||||
q_bswap.h
|
q_bswap.h
|
||||||
|
@ -91,7 +95,6 @@ PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/dds/ddsi"
|
||||||
q_ddsi_discovery.h
|
q_ddsi_discovery.h
|
||||||
q_debmon.h
|
q_debmon.h
|
||||||
q_entity.h
|
q_entity.h
|
||||||
q_ephash.h
|
|
||||||
q_feature_check.h
|
q_feature_check.h
|
||||||
q_freelist.h
|
q_freelist.h
|
||||||
q_gc.h
|
q_gc.h
|
||||||
|
@ -121,6 +124,9 @@ PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/dds/ddsi"
|
||||||
q_xqos.h
|
q_xqos.h
|
||||||
sysdeps.h
|
sysdeps.h
|
||||||
)
|
)
|
||||||
|
if(ENABLE_LIFESPAN)
|
||||||
|
list(APPEND hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/dds/ddsi/ddsi_lifespan.h")
|
||||||
|
endif()
|
||||||
|
|
||||||
target_sources(ddsc
|
target_sources(ddsc
|
||||||
PRIVATE ${srcs_ddsi} ${hdrs_private_ddsi})
|
PRIVATE ${srcs_ddsi} ${hdrs_private_ddsi})
|
||||||
|
|
144
src/core/ddsi/include/dds/ddsi/ddsi_entity_index.h
Normal file
144
src/core/ddsi/include/dds/ddsi/ddsi_entity_index.h
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
/*
|
||||||
|
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||||
|
* v. 1.0 which is available at
|
||||||
|
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||||
|
*/
|
||||||
|
#ifndef DDSI_ENTITY_INDEX_H
|
||||||
|
#define DDSI_ENTITY_INDEX_H
|
||||||
|
|
||||||
|
#include "dds/ddsrt/hopscotch.h"
|
||||||
|
#include "dds/ddsi/q_entity.h"
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct entity_index;
|
||||||
|
struct ddsi_guid;
|
||||||
|
struct q_globals;
|
||||||
|
|
||||||
|
struct match_entities_range_key {
|
||||||
|
union {
|
||||||
|
struct writer wr;
|
||||||
|
struct reader rd;
|
||||||
|
struct proxy_writer pwr;
|
||||||
|
struct proxy_reader prd;
|
||||||
|
struct entity_common e;
|
||||||
|
struct generic_proxy_endpoint gpe;
|
||||||
|
} entity;
|
||||||
|
struct dds_qos xqos;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct entidx_enum
|
||||||
|
{
|
||||||
|
struct entity_index *entidx;
|
||||||
|
enum entity_kind kind;
|
||||||
|
struct entity_common *cur;
|
||||||
|
#ifndef NDEBUG
|
||||||
|
vtime_t vtime;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Readers & writers are both in a GUID- and in a GID-keyed table. If
|
||||||
|
they are in the GID-based one, they are also in the GUID-based one,
|
||||||
|
but not the way around, for two reasons:
|
||||||
|
|
||||||
|
- firstly, there are readers & writers that do not have a GID
|
||||||
|
(built-in endpoints, fictitious transient data readers),
|
||||||
|
|
||||||
|
- secondly, they are inserted first in the GUID-keyed one, and then
|
||||||
|
in the GID-keyed one.
|
||||||
|
|
||||||
|
The GID is used solely for the interface with the OpenSplice
|
||||||
|
kernel, all internal state and protocol handling is done using the
|
||||||
|
GUID. So all this means is that, e.g., a writer being deleted
|
||||||
|
becomes invisible to the network reader slightly before it
|
||||||
|
disappears in the protocol handling, or that a writer might exist
|
||||||
|
at the protocol level slightly before the network reader can use it
|
||||||
|
to transmit data. */
|
||||||
|
|
||||||
|
struct entity_index *entity_index_new (struct q_globals *gv) ddsrt_nonnull_all;
|
||||||
|
void entity_index_free (struct entity_index *ei) ddsrt_nonnull_all;
|
||||||
|
|
||||||
|
void entidx_insert_participant_guid (struct entity_index *ei, struct participant *pp) ddsrt_nonnull_all;
|
||||||
|
void entidx_insert_proxy_participant_guid (struct entity_index *ei, struct proxy_participant *proxypp) ddsrt_nonnull_all;
|
||||||
|
void entidx_insert_writer_guid (struct entity_index *ei, struct writer *wr) ddsrt_nonnull_all;
|
||||||
|
void entidx_insert_reader_guid (struct entity_index *ei, struct reader *rd) ddsrt_nonnull_all;
|
||||||
|
void entidx_insert_proxy_writer_guid (struct entity_index *ei, struct proxy_writer *pwr) ddsrt_nonnull_all;
|
||||||
|
void entidx_insert_proxy_reader_guid (struct entity_index *ei, struct proxy_reader *prd) ddsrt_nonnull_all;
|
||||||
|
|
||||||
|
void entidx_remove_participant_guid (struct entity_index *ei, struct participant *pp) ddsrt_nonnull_all;
|
||||||
|
void entidx_remove_proxy_participant_guid (struct entity_index *ei, struct proxy_participant *proxypp) ddsrt_nonnull_all;
|
||||||
|
void entidx_remove_writer_guid (struct entity_index *ei, struct writer *wr) ddsrt_nonnull_all;
|
||||||
|
void entidx_remove_reader_guid (struct entity_index *ei, struct reader *rd) ddsrt_nonnull_all;
|
||||||
|
void entidx_remove_proxy_writer_guid (struct entity_index *ei, struct proxy_writer *pwr) ddsrt_nonnull_all;
|
||||||
|
void entidx_remove_proxy_reader_guid (struct entity_index *ei, struct proxy_reader *prd) ddsrt_nonnull_all;
|
||||||
|
|
||||||
|
DDS_EXPORT void *entidx_lookup_guid_untyped (const struct entity_index *ei, const struct ddsi_guid *guid) ddsrt_nonnull_all;
|
||||||
|
DDS_EXPORT void *entidx_lookup_guid (const struct entity_index *ei, const struct ddsi_guid *guid, enum entity_kind kind) ddsrt_nonnull_all;
|
||||||
|
|
||||||
|
DDS_EXPORT struct participant *entidx_lookup_participant_guid (const struct entity_index *ei, const struct ddsi_guid *guid) ddsrt_nonnull_all;
|
||||||
|
DDS_EXPORT struct proxy_participant *entidx_lookup_proxy_participant_guid (const struct entity_index *ei, const struct ddsi_guid *guid) ddsrt_nonnull_all;
|
||||||
|
DDS_EXPORT struct writer *entidx_lookup_writer_guid (const struct entity_index *ei, const struct ddsi_guid *guid) ddsrt_nonnull_all;
|
||||||
|
DDS_EXPORT struct reader *entidx_lookup_reader_guid (const struct entity_index *ei, const struct ddsi_guid *guid) ddsrt_nonnull_all;
|
||||||
|
DDS_EXPORT struct proxy_writer *entidx_lookup_proxy_writer_guid (const struct entity_index *ei, const struct ddsi_guid *guid) ddsrt_nonnull_all;
|
||||||
|
DDS_EXPORT struct proxy_reader *entidx_lookup_proxy_reader_guid (const struct entity_index *ei, const struct ddsi_guid *guid) ddsrt_nonnull_all;
|
||||||
|
|
||||||
|
/* Enumeration of entries in the hash table:
|
||||||
|
|
||||||
|
- "next" visits at least all entries that were in the hash table at
|
||||||
|
the time of calling init and that have not subsequently been
|
||||||
|
removed;
|
||||||
|
|
||||||
|
- "next" may visit an entry more than once, but will do so only
|
||||||
|
because of rare events (i.e., resize or so);
|
||||||
|
|
||||||
|
- the order in which entries are visited is arbitrary;
|
||||||
|
|
||||||
|
- the caller must call init() before it may call next(); it must
|
||||||
|
call fini() before it may call init() again. */
|
||||||
|
struct entidx_enum_participant { struct entidx_enum st; };
|
||||||
|
struct entidx_enum_writer { struct entidx_enum st; };
|
||||||
|
struct entidx_enum_reader { struct entidx_enum st; };
|
||||||
|
struct entidx_enum_proxy_participant { struct entidx_enum st; };
|
||||||
|
struct entidx_enum_proxy_writer { struct entidx_enum st; };
|
||||||
|
struct entidx_enum_proxy_reader { struct entidx_enum st; };
|
||||||
|
|
||||||
|
void entidx_enum_init (struct entidx_enum *st, const struct entity_index *ei, enum entity_kind kind) ddsrt_nonnull_all;
|
||||||
|
void entidx_enum_init_topic (struct entidx_enum *st, const struct entity_index *gh, enum entity_kind kind, const char *topic, struct match_entities_range_key *max) ddsrt_nonnull_all;
|
||||||
|
void *entidx_enum_next_max (struct entidx_enum *st, const struct match_entities_range_key *max) ddsrt_nonnull_all;
|
||||||
|
void *entidx_enum_next (struct entidx_enum *st) ddsrt_nonnull_all;
|
||||||
|
void entidx_enum_fini (struct entidx_enum *st) ddsrt_nonnull_all;
|
||||||
|
|
||||||
|
void entidx_enum_writer_init (struct entidx_enum_writer *st, const struct entity_index *ei) ddsrt_nonnull_all;
|
||||||
|
void entidx_enum_reader_init (struct entidx_enum_reader *st, const struct entity_index *ei) ddsrt_nonnull_all;
|
||||||
|
void entidx_enum_proxy_writer_init (struct entidx_enum_proxy_writer *st, const struct entity_index *ei) ddsrt_nonnull_all;
|
||||||
|
void entidx_enum_proxy_reader_init (struct entidx_enum_proxy_reader *st, const struct entity_index *ei) ddsrt_nonnull_all;
|
||||||
|
void entidx_enum_participant_init (struct entidx_enum_participant *st, const struct entity_index *ei) ddsrt_nonnull_all;
|
||||||
|
void entidx_enum_proxy_participant_init (struct entidx_enum_proxy_participant *st, const struct entity_index *ei) ddsrt_nonnull_all;
|
||||||
|
|
||||||
|
struct writer *entidx_enum_writer_next (struct entidx_enum_writer *st) ddsrt_nonnull_all;
|
||||||
|
struct reader *entidx_enum_reader_next (struct entidx_enum_reader *st) ddsrt_nonnull_all;
|
||||||
|
struct proxy_writer *entidx_enum_proxy_writer_next (struct entidx_enum_proxy_writer *st) ddsrt_nonnull_all;
|
||||||
|
struct proxy_reader *entidx_enum_proxy_reader_next (struct entidx_enum_proxy_reader *st) ddsrt_nonnull_all;
|
||||||
|
struct participant *entidx_enum_participant_next (struct entidx_enum_participant *st) ddsrt_nonnull_all;
|
||||||
|
struct proxy_participant *entidx_enum_proxy_participant_next (struct entidx_enum_proxy_participant *st) ddsrt_nonnull_all;
|
||||||
|
|
||||||
|
void entidx_enum_writer_fini (struct entidx_enum_writer *st) ddsrt_nonnull_all;
|
||||||
|
void entidx_enum_reader_fini (struct entidx_enum_reader *st) ddsrt_nonnull_all;
|
||||||
|
void entidx_enum_proxy_writer_fini (struct entidx_enum_proxy_writer *st) ddsrt_nonnull_all;
|
||||||
|
void entidx_enum_proxy_reader_fini (struct entidx_enum_proxy_reader *st) ddsrt_nonnull_all;
|
||||||
|
void entidx_enum_participant_fini (struct entidx_enum_participant *st) ddsrt_nonnull_all;
|
||||||
|
void entidx_enum_proxy_participant_fini (struct entidx_enum_proxy_participant *st) ddsrt_nonnull_all;
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* DDSI_ENTITY_INDEX_H */
|
61
src/core/ddsi/include/dds/ddsi/ddsi_lifespan.h
Normal file
61
src/core/ddsi/include/dds/ddsi/ddsi_lifespan.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||||
|
* v. 1.0 which is available at
|
||||||
|
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||||
|
*/
|
||||||
|
#ifndef DDSI_LIFESPAN_H
|
||||||
|
#define DDSI_LIFESPAN_H
|
||||||
|
|
||||||
|
#include "dds/ddsrt/fibheap.h"
|
||||||
|
#include "dds/ddsi/q_time.h"
|
||||||
|
#include "dds/ddsi/q_globals.h"
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef nn_mtime_t (*sample_expired_cb_t)(void *hc, nn_mtime_t tnow);
|
||||||
|
|
||||||
|
struct lifespan_adm {
|
||||||
|
ddsrt_fibheap_t ls_exp_heap; /* heap for sample expiration (lifespan) */
|
||||||
|
struct xevent *evt; /* xevent that triggers for sample with earliest expiration */
|
||||||
|
sample_expired_cb_t sample_expired_cb; /* callback for expired sample; this cb can use lifespan_next_expired_locked to get next expired sample */
|
||||||
|
size_t fh_offset; /* offset of lifespan_adm element in whc or rhc */
|
||||||
|
size_t fhn_offset; /* offset of lifespan_fhnode element in whc or rhc node (sample) */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lifespan_fhnode {
|
||||||
|
ddsrt_fibheap_node_t heapnode;
|
||||||
|
nn_mtime_t t_expire;
|
||||||
|
};
|
||||||
|
|
||||||
|
DDS_EXPORT void lifespan_init (const struct q_globals *gv, struct lifespan_adm *lifespan_adm, size_t fh_offset, size_t fh_node_offset, sample_expired_cb_t sample_expired_cb);
|
||||||
|
DDS_EXPORT void lifespan_fini (const struct lifespan_adm *lifespan_adm);
|
||||||
|
DDS_EXPORT nn_mtime_t lifespan_next_expired_locked (const struct lifespan_adm *lifespan_adm, nn_mtime_t tnow, void **sample);
|
||||||
|
DDS_EXPORT void lifespan_register_sample_real (struct lifespan_adm *lifespan_adm, struct lifespan_fhnode *node);
|
||||||
|
DDS_EXPORT void lifespan_unregister_sample_real (struct lifespan_adm *lifespan_adm, struct lifespan_fhnode *node);
|
||||||
|
|
||||||
|
inline void lifespan_register_sample_locked (struct lifespan_adm *lifespan_adm, struct lifespan_fhnode *node)
|
||||||
|
{
|
||||||
|
if (node->t_expire.v != T_NEVER)
|
||||||
|
lifespan_register_sample_real (lifespan_adm, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void lifespan_unregister_sample_locked (struct lifespan_adm *lifespan_adm, struct lifespan_fhnode *node)
|
||||||
|
{
|
||||||
|
if (node->t_expire.v != T_NEVER)
|
||||||
|
lifespan_unregister_sample_real (lifespan_adm, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* DDSI_LIFESPAN_H */
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
/* DDS_EXPORT inline i.c.w. __attributes__((visibility...)) and some compilers: */
|
/* DDS_EXPORT inline i.c.w. __attributes__((visibility...)) and some compilers: */
|
||||||
#include "dds/ddsrt/attributes.h"
|
#include "dds/ddsrt/attributes.h"
|
||||||
#include "dds/ddsi/ddsi_guid.h"
|
#include "dds/ddsi/ddsi_guid.h"
|
||||||
|
#include "dds/ddsi/q_time.h"
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -38,6 +39,9 @@ struct ddsi_writer_info
|
||||||
bool auto_dispose;
|
bool auto_dispose;
|
||||||
int32_t ownership_strength;
|
int32_t ownership_strength;
|
||||||
uint64_t iid;
|
uint64_t iid;
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
nn_mtime_t lifespan_exp;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*ddsi_rhc_free_t) (struct ddsi_rhc *rhc);
|
typedef void (*ddsi_rhc_free_t) (struct ddsi_rhc *rhc);
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "dds/ddsi/q_plist.h"
|
#include "dds/ddsi/q_plist.h"
|
||||||
#include "dds/ddsi/q_protocol.h"
|
#include "dds/ddsi/q_protocol.h"
|
||||||
#include "dds/ddsi/q_lat_estim.h"
|
#include "dds/ddsi/q_lat_estim.h"
|
||||||
#include "dds/ddsi/q_ephash.h"
|
|
||||||
#include "dds/ddsi/q_hbcontrol.h"
|
#include "dds/ddsi/q_hbcontrol.h"
|
||||||
#include "dds/ddsi/q_feature_check.h"
|
#include "dds/ddsi/q_feature_check.h"
|
||||||
#include "dds/ddsi/q_inverse_uint32_set.h"
|
#include "dds/ddsi/q_inverse_uint32_set.h"
|
||||||
|
@ -50,6 +49,15 @@ struct proxy_group;
|
||||||
struct proxy_endpoint_common;
|
struct proxy_endpoint_common;
|
||||||
typedef void (*ddsi2direct_directread_cb_t) (const struct nn_rsample_info *sampleinfo, const struct nn_rdata *fragchain, void *arg);
|
typedef void (*ddsi2direct_directread_cb_t) (const struct nn_rsample_info *sampleinfo, const struct nn_rdata *fragchain, void *arg);
|
||||||
|
|
||||||
|
enum entity_kind {
|
||||||
|
EK_PARTICIPANT,
|
||||||
|
EK_PROXY_PARTICIPANT,
|
||||||
|
EK_WRITER,
|
||||||
|
EK_PROXY_WRITER,
|
||||||
|
EK_READER,
|
||||||
|
EK_PROXY_READER
|
||||||
|
};
|
||||||
|
|
||||||
/* Liveliness changed is more complicated than just add/remove. Encode the event
|
/* Liveliness changed is more complicated than just add/remove. Encode the event
|
||||||
in status_cb_data_t::extra and ignore status_cb_data_t::add */
|
in status_cb_data_t::extra and ignore status_cb_data_t::add */
|
||||||
enum liveliness_changed_data_extra {
|
enum liveliness_changed_data_extra {
|
||||||
|
@ -162,6 +170,7 @@ struct entity_common {
|
||||||
ddsrt_mutex_t lock;
|
ddsrt_mutex_t lock;
|
||||||
bool onlylocal;
|
bool onlylocal;
|
||||||
struct q_globals *gv;
|
struct q_globals *gv;
|
||||||
|
ddsrt_avl_node_t all_entities_avlnode;
|
||||||
|
|
||||||
/* QoS changes always lock the entity itself, and additionally
|
/* QoS changes always lock the entity itself, and additionally
|
||||||
(and within the scope of the entity lock) acquire qos_lock
|
(and within the scope of the entity lock) acquire qos_lock
|
||||||
|
@ -381,6 +390,11 @@ struct proxy_endpoint_common
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct generic_proxy_endpoint {
|
||||||
|
struct entity_common e;
|
||||||
|
struct proxy_endpoint_common c;
|
||||||
|
};
|
||||||
|
|
||||||
struct proxy_writer {
|
struct proxy_writer {
|
||||||
struct entity_common e;
|
struct entity_common e;
|
||||||
struct proxy_endpoint_common c;
|
struct proxy_endpoint_common c;
|
||||||
|
@ -688,7 +702,9 @@ int proxy_writer_set_notalive (struct proxy_writer *pwr, bool notify);
|
||||||
void proxy_writer_set_notalive_guid (struct q_globals *gv, const struct ddsi_guid *pwrguid, bool notify);
|
void proxy_writer_set_notalive_guid (struct q_globals *gv, const struct ddsi_guid *pwrguid, bool notify);
|
||||||
|
|
||||||
int new_proxy_group (const struct ddsi_guid *guid, const char *name, const struct dds_qos *xqos, nn_wctime_t timestamp);
|
int new_proxy_group (const struct ddsi_guid *guid, const char *name, const struct dds_qos *xqos, nn_wctime_t timestamp);
|
||||||
void delete_proxy_group (struct ephash *guid_hash, const struct ddsi_guid *guid, nn_wctime_t timestamp, int isimplicit);
|
|
||||||
|
struct entity_index;
|
||||||
|
void delete_proxy_group (struct entity_index *entidx, const struct ddsi_guid *guid, nn_wctime_t timestamp, int isimplicit);
|
||||||
|
|
||||||
/* Call this to empty all address sets of all writers to stop all outgoing traffic, or to
|
/* Call this to empty all address sets of all writers to stop all outgoing traffic, or to
|
||||||
rebuild them all (which only makes sense after previously having emptied them all). */
|
rebuild them all (which only makes sense after previously having emptied them all). */
|
||||||
|
@ -697,7 +713,7 @@ void rebuild_or_clear_writer_addrsets(struct q_globals *gv, int rebuild);
|
||||||
void local_reader_ary_setfastpath_ok (struct local_reader_ary *x, bool fastpath_ok);
|
void local_reader_ary_setfastpath_ok (struct local_reader_ary *x, bool fastpath_ok);
|
||||||
|
|
||||||
struct ddsi_writer_info;
|
struct ddsi_writer_info;
|
||||||
DDS_EXPORT void ddsi_make_writer_info(struct ddsi_writer_info *wrinfo, const struct entity_common *e, const struct dds_qos *xqos);
|
DDS_EXPORT void ddsi_make_writer_info(struct ddsi_writer_info *wrinfo, const struct entity_common *e, const struct dds_qos *xqos, uint32_t statusinfo);
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,143 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
|
||||||
*
|
|
||||||
* This program and the accompanying materials are made available under the
|
|
||||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
|
||||||
* v. 1.0 which is available at
|
|
||||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
|
||||||
*/
|
|
||||||
#ifndef Q_EPHASH_H
|
|
||||||
#define Q_EPHASH_H
|
|
||||||
|
|
||||||
#include "dds/ddsrt/hopscotch.h"
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct ephash;
|
|
||||||
struct participant;
|
|
||||||
struct reader;
|
|
||||||
struct writer;
|
|
||||||
struct proxy_participant;
|
|
||||||
struct proxy_reader;
|
|
||||||
struct proxy_writer;
|
|
||||||
struct ddsi_guid;
|
|
||||||
|
|
||||||
enum entity_kind {
|
|
||||||
EK_PARTICIPANT,
|
|
||||||
EK_PROXY_PARTICIPANT,
|
|
||||||
EK_WRITER,
|
|
||||||
EK_PROXY_WRITER,
|
|
||||||
EK_READER,
|
|
||||||
EK_PROXY_READER
|
|
||||||
};
|
|
||||||
#define EK_NKINDS ((int) EK_PROXY_READER + 1)
|
|
||||||
|
|
||||||
struct ephash_enum
|
|
||||||
{
|
|
||||||
struct ddsrt_chh_iter it;
|
|
||||||
enum entity_kind kind;
|
|
||||||
struct entity_common *cur;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Readers & writers are both in a GUID- and in a GID-keyed table. If
|
|
||||||
they are in the GID-based one, they are also in the GUID-based one,
|
|
||||||
but not the way around, for two reasons:
|
|
||||||
|
|
||||||
- firstly, there are readers & writers that do not have a GID
|
|
||||||
(built-in endpoints, fictitious transient data readers),
|
|
||||||
|
|
||||||
- secondly, they are inserted first in the GUID-keyed one, and then
|
|
||||||
in the GID-keyed one.
|
|
||||||
|
|
||||||
The GID is used solely for the interface with the OpenSplice
|
|
||||||
kernel, all internal state and protocol handling is done using the
|
|
||||||
GUID. So all this means is that, e.g., a writer being deleted
|
|
||||||
becomes invisible to the network reader slightly before it
|
|
||||||
disappears in the protocol handling, or that a writer might exist
|
|
||||||
at the protocol level slightly before the network reader can use it
|
|
||||||
to transmit data. */
|
|
||||||
|
|
||||||
struct q_globals;
|
|
||||||
struct ephash *ephash_new (struct q_globals *gv);
|
|
||||||
void ephash_free (struct ephash *ephash);
|
|
||||||
|
|
||||||
void ephash_insert_participant_guid (struct ephash *eh, struct participant *pp);
|
|
||||||
void ephash_insert_proxy_participant_guid (struct ephash *eh, struct proxy_participant *proxypp);
|
|
||||||
void ephash_insert_writer_guid (struct ephash *eh, struct writer *wr);
|
|
||||||
void ephash_insert_reader_guid (struct ephash *eh, struct reader *rd);
|
|
||||||
void ephash_insert_proxy_writer_guid (struct ephash *eh, struct proxy_writer *pwr);
|
|
||||||
void ephash_insert_proxy_reader_guid (struct ephash *eh, struct proxy_reader *prd);
|
|
||||||
|
|
||||||
void ephash_remove_participant_guid (struct ephash *eh, struct participant *pp);
|
|
||||||
void ephash_remove_proxy_participant_guid (struct ephash *eh, struct proxy_participant *proxypp);
|
|
||||||
void ephash_remove_writer_guid (struct ephash *eh, struct writer *wr);
|
|
||||||
void ephash_remove_reader_guid (struct ephash *eh, struct reader *rd);
|
|
||||||
void ephash_remove_proxy_writer_guid (struct ephash *eh, struct proxy_writer *pwr);
|
|
||||||
void ephash_remove_proxy_reader_guid (struct ephash *eh, struct proxy_reader *prd);
|
|
||||||
|
|
||||||
DDS_EXPORT void *ephash_lookup_guid_untyped (const struct ephash *eh, const struct ddsi_guid *guid);
|
|
||||||
DDS_EXPORT void *ephash_lookup_guid (const struct ephash *eh, const struct ddsi_guid *guid, enum entity_kind kind);
|
|
||||||
|
|
||||||
DDS_EXPORT struct participant *ephash_lookup_participant_guid (const struct ephash *eh, const struct ddsi_guid *guid);
|
|
||||||
DDS_EXPORT struct proxy_participant *ephash_lookup_proxy_participant_guid (const struct ephash *eh, const struct ddsi_guid *guid);
|
|
||||||
DDS_EXPORT struct writer *ephash_lookup_writer_guid (const struct ephash *eh, const struct ddsi_guid *guid);
|
|
||||||
DDS_EXPORT struct reader *ephash_lookup_reader_guid (const struct ephash *eh, const struct ddsi_guid *guid);
|
|
||||||
DDS_EXPORT struct proxy_writer *ephash_lookup_proxy_writer_guid (const struct ephash *eh, const struct ddsi_guid *guid);
|
|
||||||
DDS_EXPORT struct proxy_reader *ephash_lookup_proxy_reader_guid (const struct ephash *eh, const struct ddsi_guid *guid);
|
|
||||||
|
|
||||||
|
|
||||||
/* Enumeration of entries in the hash table:
|
|
||||||
|
|
||||||
- "next" visits at least all entries that were in the hash table at
|
|
||||||
the time of calling init and that have not subsequently been
|
|
||||||
removed;
|
|
||||||
|
|
||||||
- "next" may visit an entry more than once, but will do so only
|
|
||||||
because of rare events (i.e., resize or so);
|
|
||||||
|
|
||||||
- the order in which entries are visited is arbitrary;
|
|
||||||
|
|
||||||
- the caller must call init() before it may call next(); it must
|
|
||||||
call fini() before it may call init() again. */
|
|
||||||
struct ephash_enum_participant { struct ephash_enum st; };
|
|
||||||
struct ephash_enum_writer { struct ephash_enum st; };
|
|
||||||
struct ephash_enum_reader { struct ephash_enum st; };
|
|
||||||
struct ephash_enum_proxy_participant { struct ephash_enum st; };
|
|
||||||
struct ephash_enum_proxy_writer { struct ephash_enum st; };
|
|
||||||
struct ephash_enum_proxy_reader { struct ephash_enum st; };
|
|
||||||
|
|
||||||
void ephash_enum_init (struct ephash_enum *st, const struct ephash *eh, enum entity_kind kind);
|
|
||||||
void *ephash_enum_next (struct ephash_enum *st);
|
|
||||||
void ephash_enum_fini (struct ephash_enum *st);
|
|
||||||
|
|
||||||
void ephash_enum_writer_init (struct ephash_enum_writer *st, const struct ephash *eh);
|
|
||||||
void ephash_enum_reader_init (struct ephash_enum_reader *st, const struct ephash *eh);
|
|
||||||
void ephash_enum_proxy_writer_init (struct ephash_enum_proxy_writer *st, const struct ephash *eh);
|
|
||||||
void ephash_enum_proxy_reader_init (struct ephash_enum_proxy_reader *st, const struct ephash *eh);
|
|
||||||
void ephash_enum_participant_init (struct ephash_enum_participant *st, const struct ephash *eh);
|
|
||||||
void ephash_enum_proxy_participant_init (struct ephash_enum_proxy_participant *st, const struct ephash *eh);
|
|
||||||
|
|
||||||
struct writer *ephash_enum_writer_next (struct ephash_enum_writer *st);
|
|
||||||
struct reader *ephash_enum_reader_next (struct ephash_enum_reader *st);
|
|
||||||
struct proxy_writer *ephash_enum_proxy_writer_next (struct ephash_enum_proxy_writer *st);
|
|
||||||
struct proxy_reader *ephash_enum_proxy_reader_next (struct ephash_enum_proxy_reader *st);
|
|
||||||
struct participant *ephash_enum_participant_next (struct ephash_enum_participant *st);
|
|
||||||
struct proxy_participant *ephash_enum_proxy_participant_next (struct ephash_enum_proxy_participant *st);
|
|
||||||
|
|
||||||
void ephash_enum_writer_fini (struct ephash_enum_writer *st);
|
|
||||||
void ephash_enum_reader_fini (struct ephash_enum_reader *st);
|
|
||||||
void ephash_enum_proxy_writer_fini (struct ephash_enum_proxy_writer *st);
|
|
||||||
void ephash_enum_proxy_reader_fini (struct ephash_enum_proxy_reader *st);
|
|
||||||
void ephash_enum_participant_fini (struct ephash_enum_participant *st);
|
|
||||||
void ephash_enum_proxy_participant_fini (struct ephash_enum_proxy_participant *st);
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* Q_EPHASH_H */
|
|
|
@ -38,7 +38,7 @@ struct nn_defrag;
|
||||||
struct addrset;
|
struct addrset;
|
||||||
struct xeventq;
|
struct xeventq;
|
||||||
struct gcreq_queue;
|
struct gcreq_queue;
|
||||||
struct ephash;
|
struct entity_index;
|
||||||
struct lease;
|
struct lease;
|
||||||
struct ddsi_tran_conn;
|
struct ddsi_tran_conn;
|
||||||
struct ddsi_tran_listener;
|
struct ddsi_tran_listener;
|
||||||
|
@ -93,9 +93,8 @@ struct q_globals {
|
||||||
struct ddsi_tkmap * m_tkmap;
|
struct ddsi_tkmap * m_tkmap;
|
||||||
|
|
||||||
/* Hash tables for participants, readers, writers, proxy
|
/* Hash tables for participants, readers, writers, proxy
|
||||||
participants, proxy readers and proxy writers by GUID
|
participants, proxy readers and proxy writers by GUID. */
|
||||||
(guid_hash) */
|
struct entity_index *entity_index;
|
||||||
struct ephash *guid_hash;
|
|
||||||
|
|
||||||
/* Timed events admin */
|
/* Timed events admin */
|
||||||
struct xeventq *xevents;
|
struct xeventq *xevents;
|
||||||
|
|
|
@ -18,6 +18,7 @@ extern "C" {
|
||||||
|
|
||||||
struct writer;
|
struct writer;
|
||||||
struct whc_state;
|
struct whc_state;
|
||||||
|
struct proxy_reader;
|
||||||
|
|
||||||
struct hbcontrol {
|
struct hbcontrol {
|
||||||
nn_mtime_t t_of_last_write;
|
nn_mtime_t t_of_last_write;
|
||||||
|
|
|
@ -46,6 +46,9 @@ typedef struct {
|
||||||
int64_t v;
|
int64_t v;
|
||||||
} nn_etime_t;
|
} nn_etime_t;
|
||||||
|
|
||||||
|
#define NN_MTIME_NEVER ((nn_mtime_t) { T_NEVER })
|
||||||
|
#define NN_WCTIME_NEVER ((nn_wctime_t) { T_NEVER })
|
||||||
|
#define NN_ETIME_NEVER ((nn_etime_t) { T_NEVER })
|
||||||
#define NN_WCTIME_INVALID ((nn_wctime_t) { INT64_MIN })
|
#define NN_WCTIME_INVALID ((nn_wctime_t) { INT64_MIN })
|
||||||
|
|
||||||
int valid_ddsi_timestamp (ddsi_time_t t);
|
int valid_ddsi_timestamp (ddsi_time_t t);
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#define Q_WHC_H
|
#define Q_WHC_H
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include "dds/ddsi/q_time.h"
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -72,7 +73,7 @@ typedef void (*whc_free_t)(struct whc *whc);
|
||||||
reliable readers that have not acknowledged all data */
|
reliable readers that have not acknowledged all data */
|
||||||
/* max_drop_seq must go soon, it's way too ugly. */
|
/* max_drop_seq must go soon, it's way too ugly. */
|
||||||
/* plist may be NULL or ddsrt_malloc'd, WHC takes ownership of plist */
|
/* plist may be NULL or ddsrt_malloc'd, WHC takes ownership of plist */
|
||||||
typedef int (*whc_insert_t)(struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk);
|
typedef int (*whc_insert_t)(struct whc *whc, seqno_t max_drop_seq, seqno_t seq, nn_mtime_t exp, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk);
|
||||||
typedef uint32_t (*whc_downgrade_to_volatile_t)(struct whc *whc, struct whc_state *st);
|
typedef uint32_t (*whc_downgrade_to_volatile_t)(struct whc *whc, struct whc_state *st);
|
||||||
typedef uint32_t (*whc_remove_acked_messages_t)(struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list);
|
typedef uint32_t (*whc_remove_acked_messages_t)(struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list);
|
||||||
typedef void (*whc_free_deferred_free_list_t)(struct whc *whc, struct whc_node *deferred_free_list);
|
typedef void (*whc_free_deferred_free_list_t)(struct whc *whc, struct whc_node *deferred_free_list);
|
||||||
|
@ -120,8 +121,8 @@ inline bool whc_sample_iter_borrow_next (struct whc_sample_iter *it, struct whc_
|
||||||
inline void whc_free (struct whc *whc) {
|
inline void whc_free (struct whc *whc) {
|
||||||
whc->ops->free (whc);
|
whc->ops->free (whc);
|
||||||
}
|
}
|
||||||
inline int whc_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk) {
|
inline int whc_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, nn_mtime_t exp, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk) {
|
||||||
return whc->ops->insert (whc, max_drop_seq, seq, plist, serdata, tk);
|
return whc->ops->insert (whc, max_drop_seq, seq, exp, plist, serdata, tk);
|
||||||
}
|
}
|
||||||
inline unsigned whc_downgrade_to_volatile (struct whc *whc, struct whc_state *st) {
|
inline unsigned whc_downgrade_to_volatile (struct whc *whc, struct whc_state *st) {
|
||||||
return whc->ops->downgrade_to_volatile (whc, st);
|
return whc->ops->downgrade_to_volatile (whc, st);
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
#ifndef NN_XEVENT_H
|
#ifndef NN_XEVENT_H
|
||||||
#define NN_XEVENT_H
|
#define NN_XEVENT_H
|
||||||
|
|
||||||
|
#include "dds/ddsrt/retcode.h"
|
||||||
|
#include "dds/ddsi/ddsi_guid.h"
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -30,6 +33,7 @@ struct xevent;
|
||||||
struct xeventq;
|
struct xeventq;
|
||||||
struct proxy_writer;
|
struct proxy_writer;
|
||||||
struct proxy_reader;
|
struct proxy_reader;
|
||||||
|
struct nn_xmsg;
|
||||||
|
|
||||||
struct xeventq *xeventq_new
|
struct xeventq *xeventq_new
|
||||||
(
|
(
|
||||||
|
@ -55,6 +59,7 @@ DDS_EXPORT int qxev_msg_rexmit_wrlock_held (struct xeventq *evq, struct nn_xmsg
|
||||||
|
|
||||||
/* All of the following lock EVQ for the duration of the operation */
|
/* All of the following lock EVQ for the duration of the operation */
|
||||||
DDS_EXPORT void delete_xevent (struct xevent *ev);
|
DDS_EXPORT void delete_xevent (struct xevent *ev);
|
||||||
|
DDS_EXPORT void delete_xevent_callback (struct xevent *ev);
|
||||||
DDS_EXPORT int resched_xevent_if_earlier (struct xevent *ev, nn_mtime_t tsched);
|
DDS_EXPORT int resched_xevent_if_earlier (struct xevent *ev, nn_mtime_t tsched);
|
||||||
|
|
||||||
DDS_EXPORT struct xevent *qxev_heartbeat (struct xeventq *evq, nn_mtime_t tsched, const ddsi_guid_t *wr_guid);
|
DDS_EXPORT struct xevent *qxev_heartbeat (struct xeventq *evq, nn_mtime_t tsched, const ddsi_guid_t *wr_guid);
|
||||||
|
|
578
src/core/ddsi/src/ddsi_entity_index.c
Normal file
578
src/core/ddsi/src/ddsi_entity_index.c
Normal file
|
@ -0,0 +1,578 @@
|
||||||
|
/*
|
||||||
|
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||||
|
* v. 1.0 which is available at
|
||||||
|
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||||
|
*/
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "dds/ddsrt/heap.h"
|
||||||
|
#include "dds/ddsrt/misc.h"
|
||||||
|
|
||||||
|
#include "dds/ddsrt/hopscotch.h"
|
||||||
|
#include "dds/ddsrt/avl.h"
|
||||||
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
|
#include "dds/ddsi/q_config.h"
|
||||||
|
#include "dds/ddsi/q_globals.h"
|
||||||
|
#include "dds/ddsi/q_entity.h"
|
||||||
|
#include "dds/ddsi/q_gc.h"
|
||||||
|
#include "dds/ddsi/q_rtps.h" /* guid_t */
|
||||||
|
#include "dds/ddsi/q_thread.h" /* for assert(thread is awake) */
|
||||||
|
|
||||||
|
struct entity_index {
|
||||||
|
struct ddsrt_chh *guid_hash;
|
||||||
|
ddsrt_mutex_t all_entities_lock;
|
||||||
|
ddsrt_avl_tree_t all_entities;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint64_t unihashconsts[] = {
|
||||||
|
UINT64_C (16292676669999574021),
|
||||||
|
UINT64_C (10242350189706880077),
|
||||||
|
UINT64_C (12844332200329132887),
|
||||||
|
UINT64_C (16728792139623414127)
|
||||||
|
};
|
||||||
|
|
||||||
|
static int all_entities_compare (const void *va, const void *vb);
|
||||||
|
static const ddsrt_avl_treedef_t all_entities_treedef =
|
||||||
|
DDSRT_AVL_TREEDEF_INITIALIZER (offsetof (struct entity_common, all_entities_avlnode), 0, all_entities_compare, 0);
|
||||||
|
|
||||||
|
static uint32_t hash_entity_guid (const struct entity_common *c)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(uint32_t) (((((uint32_t) c->guid.prefix.u[0] + unihashconsts[0]) *
|
||||||
|
((uint32_t) c->guid.prefix.u[1] + unihashconsts[1])) +
|
||||||
|
(((uint32_t) c->guid.prefix.u[2] + unihashconsts[2]) *
|
||||||
|
((uint32_t) c->guid.entityid.u + unihashconsts[3])))
|
||||||
|
>> 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t hash_entity_guid_wrapper (const void *c)
|
||||||
|
{
|
||||||
|
return hash_entity_guid (c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entity_guid_eq (const struct entity_common *a, const struct entity_common *b)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
a->guid.prefix.u[0] == b->guid.prefix.u[0] && a->guid.prefix.u[1] == b->guid.prefix.u[1] &&
|
||||||
|
a->guid.prefix.u[2] == b->guid.prefix.u[2] && a->guid.entityid.u == b->guid.entityid.u;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entity_guid_eq_wrapper (const void *a, const void *b)
|
||||||
|
{
|
||||||
|
return entity_guid_eq (a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int all_entities_compare_isbuiltin (const struct entity_common *e, nn_vendorid_t vendor)
|
||||||
|
{
|
||||||
|
const unsigned char *guid_bytes = (const unsigned char *) &e->guid;
|
||||||
|
if (guid_bytes[0] != 0 && guid_bytes[0] != 0xff)
|
||||||
|
return is_builtin_endpoint (e->guid.entityid, vendor);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (size_t i = 1; i < sizeof (e->guid); i++)
|
||||||
|
if (guid_bytes[i] != guid_bytes[0])
|
||||||
|
return is_builtin_endpoint (e->guid.entityid, vendor) && !is_local_orphan_endpoint (e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int all_entities_compare (const void *va, const void *vb)
|
||||||
|
{
|
||||||
|
const struct entity_common *a = va;
|
||||||
|
const struct entity_common *b = vb;
|
||||||
|
const char *tp_a = "";
|
||||||
|
const char *tp_b = "";
|
||||||
|
int cmpres;
|
||||||
|
|
||||||
|
if (a->kind != b->kind)
|
||||||
|
return (int) a->kind - (int) b->kind;
|
||||||
|
|
||||||
|
switch (a->kind)
|
||||||
|
{
|
||||||
|
case EK_PARTICIPANT:
|
||||||
|
case EK_PROXY_PARTICIPANT:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EK_WRITER: {
|
||||||
|
const struct writer *wra = va;
|
||||||
|
const struct writer *wrb = vb;
|
||||||
|
if (!all_entities_compare_isbuiltin (a, NN_VENDORID_ECLIPSE)) {
|
||||||
|
assert ((wra->xqos->present & QP_TOPIC_NAME) && wra->xqos->topic_name);
|
||||||
|
tp_a = wra->xqos->topic_name;
|
||||||
|
}
|
||||||
|
if (!all_entities_compare_isbuiltin (b, NN_VENDORID_ECLIPSE)) {
|
||||||
|
assert ((wrb->xqos->present & QP_TOPIC_NAME) && wrb->xqos->topic_name);
|
||||||
|
tp_b = wrb->xqos->topic_name;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EK_READER: {
|
||||||
|
const struct reader *rda = va;
|
||||||
|
const struct reader *rdb = vb;
|
||||||
|
if (!all_entities_compare_isbuiltin (a, NN_VENDORID_ECLIPSE)) {
|
||||||
|
assert ((rda->xqos->present & QP_TOPIC_NAME) && rda->xqos->topic_name);
|
||||||
|
tp_a = rda->xqos->topic_name;
|
||||||
|
}
|
||||||
|
if (!all_entities_compare_isbuiltin (b, NN_VENDORID_ECLIPSE)) {
|
||||||
|
assert ((rdb->xqos->present & QP_TOPIC_NAME) && rdb->xqos->topic_name);
|
||||||
|
tp_b = rdb->xqos->topic_name;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EK_PROXY_WRITER:
|
||||||
|
case EK_PROXY_READER: {
|
||||||
|
const struct generic_proxy_endpoint *ga = va;
|
||||||
|
const struct generic_proxy_endpoint *gb = vb;
|
||||||
|
if (!all_entities_compare_isbuiltin (a, ga->c.vendor)) {
|
||||||
|
assert ((ga->c.xqos->present & QP_TOPIC_NAME) && ga->c.xqos->topic_name);
|
||||||
|
tp_a = ga->c.xqos->topic_name;
|
||||||
|
}
|
||||||
|
if (!all_entities_compare_isbuiltin (b, gb->c.vendor)) {
|
||||||
|
assert ((gb->c.xqos->present & QP_TOPIC_NAME) && gb->c.xqos->topic_name);
|
||||||
|
tp_b = gb->c.xqos->topic_name;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((cmpres = strcmp (tp_a, tp_b)) != 0)
|
||||||
|
return cmpres;
|
||||||
|
else
|
||||||
|
return memcmp (&a->guid, &b->guid, sizeof (a->guid));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void match_endpoint_range (enum entity_kind kind, const char *tp, struct match_entities_range_key *min, struct match_entities_range_key *max)
|
||||||
|
{
|
||||||
|
/* looking for entities of kind KIND; initialize fake entities such that they are
|
||||||
|
valid input to all_entities_compare and that span the range of all possibly
|
||||||
|
matching endpoints. */
|
||||||
|
min->entity.e.kind = max->entity.e.kind = kind;
|
||||||
|
memset (&min->entity.e.guid, 0x00, sizeof (min->entity.e.guid));
|
||||||
|
memset (&max->entity.e.guid, 0xff, sizeof (max->entity.e.guid));
|
||||||
|
min->xqos.present = max->xqos.present = QP_TOPIC_NAME;
|
||||||
|
min->xqos.topic_name = max->xqos.topic_name = (char *) tp;
|
||||||
|
switch (kind)
|
||||||
|
{
|
||||||
|
case EK_PARTICIPANT:
|
||||||
|
case EK_PROXY_PARTICIPANT:
|
||||||
|
break;
|
||||||
|
case EK_WRITER:
|
||||||
|
min->entity.wr.xqos = &min->xqos;
|
||||||
|
max->entity.wr.xqos = &max->xqos;
|
||||||
|
break;
|
||||||
|
case EK_READER:
|
||||||
|
min->entity.rd.xqos = &min->xqos;
|
||||||
|
max->entity.rd.xqos = &max->xqos;
|
||||||
|
break;
|
||||||
|
case EK_PROXY_WRITER:
|
||||||
|
case EK_PROXY_READER:
|
||||||
|
min->entity.gpe.c.vendor = max->entity.gpe.c.vendor = NN_VENDORID_ECLIPSE;
|
||||||
|
min->entity.gpe.c.xqos = &min->xqos;
|
||||||
|
max->entity.gpe.c.xqos = &max->xqos;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void match_entity_kind_min (enum entity_kind kind, struct match_entities_range_key *min)
|
||||||
|
{
|
||||||
|
/* looking for entities of kind KIND; initialize fake entities such that they are
|
||||||
|
valid input to all_entities_compare and that span the range of all possibly
|
||||||
|
matching endpoints. */
|
||||||
|
min->entity.e.kind = kind;
|
||||||
|
memset (&min->entity.e.guid, 0x00, sizeof (min->entity.e.guid));
|
||||||
|
min->xqos.present = QP_TOPIC_NAME;
|
||||||
|
min->xqos.topic_name = "";
|
||||||
|
switch (kind)
|
||||||
|
{
|
||||||
|
case EK_PARTICIPANT:
|
||||||
|
case EK_PROXY_PARTICIPANT:
|
||||||
|
break;
|
||||||
|
case EK_WRITER:
|
||||||
|
min->entity.wr.xqos = &min->xqos;
|
||||||
|
break;
|
||||||
|
case EK_READER:
|
||||||
|
min->entity.rd.xqos = &min->xqos;
|
||||||
|
break;
|
||||||
|
case EK_PROXY_WRITER:
|
||||||
|
case EK_PROXY_READER:
|
||||||
|
min->entity.gpe.c.vendor = NN_VENDORID_ECLIPSE;
|
||||||
|
min->entity.gpe.c.xqos = &min->xqos;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gc_buckets_cb (struct gcreq *gcreq)
|
||||||
|
{
|
||||||
|
void *bs = gcreq->arg;
|
||||||
|
gcreq_free (gcreq);
|
||||||
|
ddsrt_free (bs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gc_buckets (void *bs, void *varg)
|
||||||
|
{
|
||||||
|
struct q_globals *gv = varg;
|
||||||
|
struct gcreq *gcreq = gcreq_new (gv->gcreq_queue, gc_buckets_cb);
|
||||||
|
gcreq->arg = bs;
|
||||||
|
gcreq_enqueue (gcreq);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct entity_index *entity_index_new (struct q_globals *gv)
|
||||||
|
{
|
||||||
|
struct entity_index *entidx;
|
||||||
|
entidx = ddsrt_malloc (sizeof (*entidx));
|
||||||
|
entidx->guid_hash = ddsrt_chh_new (32, hash_entity_guid_wrapper, entity_guid_eq_wrapper, gc_buckets, gv);
|
||||||
|
if (entidx->guid_hash == NULL) {
|
||||||
|
ddsrt_free (entidx);
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
ddsrt_mutex_init (&entidx->all_entities_lock);
|
||||||
|
ddsrt_avl_init (&all_entities_treedef, &entidx->all_entities);
|
||||||
|
return entidx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void entity_index_free (struct entity_index *entidx)
|
||||||
|
{
|
||||||
|
ddsrt_avl_free (&all_entities_treedef, &entidx->all_entities, 0);
|
||||||
|
ddsrt_mutex_destroy (&entidx->all_entities_lock);
|
||||||
|
ddsrt_chh_free (entidx->guid_hash);
|
||||||
|
entidx->guid_hash = NULL;
|
||||||
|
ddsrt_free (entidx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_to_all_entities (struct entity_index *ei, struct entity_common *e)
|
||||||
|
{
|
||||||
|
ddsrt_mutex_lock (&ei->all_entities_lock);
|
||||||
|
assert (ddsrt_avl_lookup (&all_entities_treedef, &ei->all_entities, e) == NULL);
|
||||||
|
ddsrt_avl_insert (&all_entities_treedef, &ei->all_entities, e);
|
||||||
|
ddsrt_mutex_unlock (&ei->all_entities_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void remove_from_all_entities (struct entity_index *ei, struct entity_common *e)
|
||||||
|
{
|
||||||
|
ddsrt_mutex_lock (&ei->all_entities_lock);
|
||||||
|
assert (ddsrt_avl_lookup (&all_entities_treedef, &ei->all_entities, e) != NULL);
|
||||||
|
ddsrt_avl_delete (&all_entities_treedef, &ei->all_entities, e);
|
||||||
|
ddsrt_mutex_unlock (&ei->all_entities_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void entity_index_insert (struct entity_index *ei, struct entity_common *e)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
x = ddsrt_chh_add (ei->guid_hash, e);
|
||||||
|
(void)x;
|
||||||
|
assert (x);
|
||||||
|
add_to_all_entities (ei, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void entity_index_remove (struct entity_index *ei, struct entity_common *e)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
remove_from_all_entities (ei, e);
|
||||||
|
x = ddsrt_chh_remove (ei->guid_hash, e);
|
||||||
|
(void)x;
|
||||||
|
assert (x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *entidx_lookup_guid_untyped (const struct entity_index *ei, const struct ddsi_guid *guid)
|
||||||
|
{
|
||||||
|
/* FIXME: could (now) require guid to be first in entity_common; entity_common already is first in entity */
|
||||||
|
struct entity_common e;
|
||||||
|
e.guid = *guid;
|
||||||
|
assert (thread_is_awake ());
|
||||||
|
return ddsrt_chh_lookup (ei->guid_hash, &e);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *entidx_lookup_guid_int (const struct entity_index *ei, const struct ddsi_guid *guid, enum entity_kind kind)
|
||||||
|
{
|
||||||
|
struct entity_common *res;
|
||||||
|
if ((res = entidx_lookup_guid_untyped (ei, guid)) != NULL && res->kind == kind)
|
||||||
|
return res;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *entidx_lookup_guid (const struct entity_index *ei, const struct ddsi_guid *guid, enum entity_kind kind)
|
||||||
|
{
|
||||||
|
return entidx_lookup_guid_int (ei, guid, kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_insert_participant_guid (struct entity_index *ei, struct participant *pp)
|
||||||
|
{
|
||||||
|
entity_index_insert (ei, &pp->e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_insert_proxy_participant_guid (struct entity_index *ei, struct proxy_participant *proxypp)
|
||||||
|
{
|
||||||
|
entity_index_insert (ei, &proxypp->e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_insert_writer_guid (struct entity_index *ei, struct writer *wr)
|
||||||
|
{
|
||||||
|
entity_index_insert (ei, &wr->e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_insert_reader_guid (struct entity_index *ei, struct reader *rd)
|
||||||
|
{
|
||||||
|
entity_index_insert (ei, &rd->e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_insert_proxy_writer_guid (struct entity_index *ei, struct proxy_writer *pwr)
|
||||||
|
{
|
||||||
|
entity_index_insert (ei, &pwr->e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_insert_proxy_reader_guid (struct entity_index *ei, struct proxy_reader *prd)
|
||||||
|
{
|
||||||
|
entity_index_insert (ei, &prd->e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_remove_participant_guid (struct entity_index *ei, struct participant *pp)
|
||||||
|
{
|
||||||
|
entity_index_remove (ei, &pp->e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_remove_proxy_participant_guid (struct entity_index *ei, struct proxy_participant *proxypp)
|
||||||
|
{
|
||||||
|
entity_index_remove (ei, &proxypp->e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_remove_writer_guid (struct entity_index *ei, struct writer *wr)
|
||||||
|
{
|
||||||
|
entity_index_remove (ei, &wr->e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_remove_reader_guid (struct entity_index *ei, struct reader *rd)
|
||||||
|
{
|
||||||
|
entity_index_remove (ei, &rd->e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_remove_proxy_writer_guid (struct entity_index *ei, struct proxy_writer *pwr)
|
||||||
|
{
|
||||||
|
entity_index_remove (ei, &pwr->e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_remove_proxy_reader_guid (struct entity_index *ei, struct proxy_reader *prd)
|
||||||
|
{
|
||||||
|
entity_index_remove (ei, &prd->e);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct participant *entidx_lookup_participant_guid (const struct entity_index *ei, const struct ddsi_guid *guid)
|
||||||
|
{
|
||||||
|
DDSRT_STATIC_ASSERT (offsetof (struct participant, e) == 0);
|
||||||
|
assert (guid->entityid.u == NN_ENTITYID_PARTICIPANT);
|
||||||
|
return entidx_lookup_guid_int (ei, guid, EK_PARTICIPANT);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct proxy_participant *entidx_lookup_proxy_participant_guid (const struct entity_index *ei, const struct ddsi_guid *guid)
|
||||||
|
{
|
||||||
|
DDSRT_STATIC_ASSERT (offsetof (struct proxy_participant, e) == 0);
|
||||||
|
assert (guid->entityid.u == NN_ENTITYID_PARTICIPANT);
|
||||||
|
return entidx_lookup_guid_int (ei, guid, EK_PROXY_PARTICIPANT);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct writer *entidx_lookup_writer_guid (const struct entity_index *ei, const struct ddsi_guid *guid)
|
||||||
|
{
|
||||||
|
DDSRT_STATIC_ASSERT (offsetof (struct writer, e) == 0);
|
||||||
|
assert (is_writer_entityid (guid->entityid));
|
||||||
|
return entidx_lookup_guid_int (ei, guid, EK_WRITER);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct reader *entidx_lookup_reader_guid (const struct entity_index *ei, const struct ddsi_guid *guid)
|
||||||
|
{
|
||||||
|
DDSRT_STATIC_ASSERT (offsetof (struct reader, e) == 0);
|
||||||
|
assert (is_reader_entityid (guid->entityid));
|
||||||
|
return entidx_lookup_guid_int (ei, guid, EK_READER);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct proxy_writer *entidx_lookup_proxy_writer_guid (const struct entity_index *ei, const struct ddsi_guid *guid)
|
||||||
|
{
|
||||||
|
DDSRT_STATIC_ASSERT (offsetof (struct proxy_writer, e) == 0);
|
||||||
|
assert (is_writer_entityid (guid->entityid));
|
||||||
|
return entidx_lookup_guid_int (ei, guid, EK_PROXY_WRITER);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct proxy_reader *entidx_lookup_proxy_reader_guid (const struct entity_index *ei, const struct ddsi_guid *guid)
|
||||||
|
{
|
||||||
|
DDSRT_STATIC_ASSERT (offsetof (struct proxy_reader, e) == 0);
|
||||||
|
assert (is_reader_entityid (guid->entityid));
|
||||||
|
return entidx_lookup_guid_int (ei, guid, EK_PROXY_READER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enumeration */
|
||||||
|
|
||||||
|
static void entidx_enum_init_minmax_int (struct entidx_enum *st, const struct entity_index *ei, struct match_entities_range_key *min)
|
||||||
|
{
|
||||||
|
/* Use a lock to protect against concurrent modification and rely on the GC not deleting
|
||||||
|
any entities while enumerating so we can rely on the (kind, topic, GUID) triple to
|
||||||
|
remain valid for looking up the next entity. With a bit of additional effort it would
|
||||||
|
be possible to allow the GC to reclaim any entities already visited, but I don't think
|
||||||
|
that additional effort is worth it. */
|
||||||
|
#ifndef NDEBUG
|
||||||
|
assert (thread_is_awake ());
|
||||||
|
st->vtime = ddsrt_atomic_ld32 (&lookup_thread_state ()->vtime);
|
||||||
|
#endif
|
||||||
|
st->entidx = (struct entity_index *) ei;
|
||||||
|
st->kind = min->entity.e.kind;
|
||||||
|
ddsrt_mutex_lock (&st->entidx->all_entities_lock);
|
||||||
|
st->cur = ddsrt_avl_lookup_succ_eq (&all_entities_treedef, &st->entidx->all_entities, min);
|
||||||
|
ddsrt_mutex_unlock (&st->entidx->all_entities_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_enum_init_topic (struct entidx_enum *st, const struct entity_index *ei, enum entity_kind kind, const char *topic, struct match_entities_range_key *max)
|
||||||
|
{
|
||||||
|
assert (kind == EK_READER || kind == EK_WRITER || kind == EK_PROXY_READER || kind == EK_PROXY_WRITER);
|
||||||
|
struct match_entities_range_key min;
|
||||||
|
match_endpoint_range (kind, topic, &min, max);
|
||||||
|
entidx_enum_init_minmax_int (st, ei, &min);
|
||||||
|
if (st->cur && all_entities_compare (st->cur, &max->entity) > 0)
|
||||||
|
st->cur = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_enum_init (struct entidx_enum *st, const struct entity_index *ei, enum entity_kind kind)
|
||||||
|
{
|
||||||
|
struct match_entities_range_key min;
|
||||||
|
match_entity_kind_min (kind, &min);
|
||||||
|
entidx_enum_init_minmax_int (st, ei, &min);
|
||||||
|
if (st->cur && st->cur->kind != st->kind)
|
||||||
|
st->cur = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_enum_writer_init (struct entidx_enum_writer *st, const struct entity_index *ei)
|
||||||
|
{
|
||||||
|
entidx_enum_init (&st->st, ei, EK_WRITER);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_enum_reader_init (struct entidx_enum_reader *st, const struct entity_index *ei)
|
||||||
|
{
|
||||||
|
entidx_enum_init (&st->st, ei, EK_READER);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_enum_proxy_writer_init (struct entidx_enum_proxy_writer *st, const struct entity_index *ei)
|
||||||
|
{
|
||||||
|
entidx_enum_init (&st->st, ei, EK_PROXY_WRITER);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_enum_proxy_reader_init (struct entidx_enum_proxy_reader *st, const struct entity_index *ei)
|
||||||
|
{
|
||||||
|
entidx_enum_init (&st->st, ei, EK_PROXY_READER);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_enum_participant_init (struct entidx_enum_participant *st, const struct entity_index *ei)
|
||||||
|
{
|
||||||
|
entidx_enum_init (&st->st, ei, EK_PARTICIPANT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_enum_proxy_participant_init (struct entidx_enum_proxy_participant *st, const struct entity_index *ei)
|
||||||
|
{
|
||||||
|
entidx_enum_init (&st->st, ei, EK_PROXY_PARTICIPANT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *entidx_enum_next (struct entidx_enum *st)
|
||||||
|
{
|
||||||
|
/* st->cur can not have been freed yet, but it may have been removed from the index */
|
||||||
|
assert (ddsrt_atomic_ld32 (&lookup_thread_state ()->vtime) == st->vtime);
|
||||||
|
void *res = st->cur;
|
||||||
|
if (st->cur)
|
||||||
|
{
|
||||||
|
ddsrt_mutex_lock (&st->entidx->all_entities_lock);
|
||||||
|
st->cur = ddsrt_avl_lookup_succ (&all_entities_treedef, &st->entidx->all_entities, st->cur);
|
||||||
|
ddsrt_mutex_unlock (&st->entidx->all_entities_lock);
|
||||||
|
if (st->cur && st->cur->kind != st->kind)
|
||||||
|
st->cur = NULL;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *entidx_enum_next_max (struct entidx_enum *st, const struct match_entities_range_key *max)
|
||||||
|
{
|
||||||
|
void *res = entidx_enum_next (st);
|
||||||
|
|
||||||
|
/* max may only make the bounds tighter */
|
||||||
|
assert (max->entity.e.kind == st->kind);
|
||||||
|
if (st->cur && all_entities_compare (st->cur, &max->entity) > 0)
|
||||||
|
st->cur = NULL;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct writer *entidx_enum_writer_next (struct entidx_enum_writer *st)
|
||||||
|
{
|
||||||
|
DDSRT_STATIC_ASSERT (offsetof (struct writer, e) == 0);
|
||||||
|
return entidx_enum_next (&st->st);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct reader *entidx_enum_reader_next (struct entidx_enum_reader *st)
|
||||||
|
{
|
||||||
|
DDSRT_STATIC_ASSERT (offsetof (struct reader, e) == 0);
|
||||||
|
return entidx_enum_next (&st->st);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct proxy_writer *entidx_enum_proxy_writer_next (struct entidx_enum_proxy_writer *st)
|
||||||
|
{
|
||||||
|
DDSRT_STATIC_ASSERT (offsetof (struct proxy_writer, e) == 0);
|
||||||
|
return entidx_enum_next (&st->st);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct proxy_reader *entidx_enum_proxy_reader_next (struct entidx_enum_proxy_reader *st)
|
||||||
|
{
|
||||||
|
DDSRT_STATIC_ASSERT (offsetof (struct proxy_reader, e) == 0);
|
||||||
|
return entidx_enum_next (&st->st);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct participant *entidx_enum_participant_next (struct entidx_enum_participant *st)
|
||||||
|
{
|
||||||
|
DDSRT_STATIC_ASSERT (offsetof (struct participant, e) == 0);
|
||||||
|
return entidx_enum_next (&st->st);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct proxy_participant *entidx_enum_proxy_participant_next (struct entidx_enum_proxy_participant *st)
|
||||||
|
{
|
||||||
|
DDSRT_STATIC_ASSERT (offsetof (struct proxy_participant, e) == 0);
|
||||||
|
return entidx_enum_next (&st->st);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_enum_fini (struct entidx_enum *st)
|
||||||
|
{
|
||||||
|
assert (ddsrt_atomic_ld32 (&lookup_thread_state ()->vtime) == st->vtime);
|
||||||
|
(void) st;
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_enum_writer_fini (struct entidx_enum_writer *st)
|
||||||
|
{
|
||||||
|
entidx_enum_fini (&st->st);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_enum_reader_fini (struct entidx_enum_reader *st)
|
||||||
|
{
|
||||||
|
entidx_enum_fini (&st->st);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_enum_proxy_writer_fini (struct entidx_enum_proxy_writer *st)
|
||||||
|
{
|
||||||
|
entidx_enum_fini (&st->st);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_enum_proxy_reader_fini (struct entidx_enum_proxy_reader *st)
|
||||||
|
{
|
||||||
|
entidx_enum_fini (&st->st);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_enum_participant_fini (struct entidx_enum_participant *st)
|
||||||
|
{
|
||||||
|
entidx_enum_fini (&st->st);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entidx_enum_proxy_participant_fini (struct entidx_enum_proxy_participant *st)
|
||||||
|
{
|
||||||
|
entidx_enum_fini (&st->st);
|
||||||
|
}
|
84
src/core/ddsi/src/ddsi_lifespan.c
Normal file
84
src/core/ddsi/src/ddsi_lifespan.c
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||||
|
* v. 1.0 which is available at
|
||||||
|
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||||
|
*/
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "dds/ddsrt/heap.h"
|
||||||
|
#include "dds/ddsrt/fibheap.h"
|
||||||
|
#include "dds/ddsi/ddsi_lifespan.h"
|
||||||
|
#include "dds/ddsi/q_time.h"
|
||||||
|
#include "dds/ddsi/q_xevent.h"
|
||||||
|
|
||||||
|
static int compare_lifespan_texp (const void *va, const void *vb)
|
||||||
|
{
|
||||||
|
const struct lifespan_fhnode *a = va;
|
||||||
|
const struct lifespan_fhnode *b = vb;
|
||||||
|
return (a->t_expire.v == b->t_expire.v) ? 0 : (a->t_expire.v < b->t_expire.v) ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ddsrt_fibheap_def_t lifespan_fhdef = DDSRT_FIBHEAPDEF_INITIALIZER(offsetof (struct lifespan_fhnode, heapnode), compare_lifespan_texp);
|
||||||
|
|
||||||
|
static void lifespan_rhc_node_exp (struct xevent *xev, void *varg, nn_mtime_t tnow)
|
||||||
|
{
|
||||||
|
struct lifespan_adm * const lifespan_adm = varg;
|
||||||
|
nn_mtime_t next_valid = lifespan_adm->sample_expired_cb((char *)lifespan_adm - lifespan_adm->fh_offset, tnow);
|
||||||
|
resched_xevent_if_earlier (xev, next_valid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Gets the sample from the fibheap in lifespan admin that was expired first. If no more
|
||||||
|
* expired samples exist in the fibheap, the expiry time (nn_mtime_t) for the next sample to
|
||||||
|
* expire is returned. If the fibheap contains no more samples, NN_MTIME_NEVER is returned */
|
||||||
|
nn_mtime_t lifespan_next_expired_locked (const struct lifespan_adm *lifespan_adm, nn_mtime_t tnow, void **sample)
|
||||||
|
{
|
||||||
|
struct lifespan_fhnode *node;
|
||||||
|
if ((node = ddsrt_fibheap_min(&lifespan_fhdef, &lifespan_adm->ls_exp_heap)) != NULL && node->t_expire.v <= tnow.v)
|
||||||
|
{
|
||||||
|
*sample = (char *)node - lifespan_adm->fhn_offset;
|
||||||
|
return (nn_mtime_t) { 0 };
|
||||||
|
}
|
||||||
|
*sample = NULL;
|
||||||
|
return (node != NULL) ? node->t_expire : NN_MTIME_NEVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lifespan_init (const struct q_globals *gv, struct lifespan_adm *lifespan_adm, size_t fh_offset, size_t fh_node_offset, sample_expired_cb_t sample_expired_cb)
|
||||||
|
{
|
||||||
|
ddsrt_fibheap_init (&lifespan_fhdef, &lifespan_adm->ls_exp_heap);
|
||||||
|
lifespan_adm->evt = qxev_callback (gv->xevents, NN_MTIME_NEVER, lifespan_rhc_node_exp, lifespan_adm);
|
||||||
|
lifespan_adm->sample_expired_cb = sample_expired_cb;
|
||||||
|
lifespan_adm->fh_offset = fh_offset;
|
||||||
|
lifespan_adm->fhn_offset = fh_node_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lifespan_fini (const struct lifespan_adm *lifespan_adm)
|
||||||
|
{
|
||||||
|
assert (ddsrt_fibheap_min (&lifespan_fhdef, &lifespan_adm->ls_exp_heap) == NULL);
|
||||||
|
delete_xevent_callback (lifespan_adm->evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline void lifespan_register_sample_locked (struct lifespan_adm *lifespan_adm, struct lifespan_fhnode *node);
|
||||||
|
|
||||||
|
void lifespan_register_sample_real (struct lifespan_adm *lifespan_adm, struct lifespan_fhnode *node)
|
||||||
|
{
|
||||||
|
ddsrt_fibheap_insert(&lifespan_fhdef, &lifespan_adm->ls_exp_heap, node);
|
||||||
|
resched_xevent_if_earlier (lifespan_adm->evt, node->t_expire);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline void lifespan_unregister_sample_locked (struct lifespan_adm *lifespan_adm, struct lifespan_fhnode *node);
|
||||||
|
|
||||||
|
void lifespan_unregister_sample_real (struct lifespan_adm *lifespan_adm, struct lifespan_fhnode *node)
|
||||||
|
{
|
||||||
|
/* Updating the scheduled event with the new shortest expiry
|
||||||
|
* is not required, because the event will be rescheduled when
|
||||||
|
* this removed node expires. Only remove the node from the
|
||||||
|
* lifespan heap */
|
||||||
|
ddsrt_fibheap_delete(&lifespan_fhdef, &lifespan_adm->ls_exp_heap, node);
|
||||||
|
}
|
|
@ -17,6 +17,7 @@
|
||||||
#include "dds/ddsi/ddsi_tkmap.h"
|
#include "dds/ddsi/ddsi_tkmap.h"
|
||||||
#include "dds/ddsi/q_bswap.h"
|
#include "dds/ddsi/q_bswap.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/ddsi/q_globals.h"
|
#include "dds/ddsi/q_globals.h"
|
||||||
#include "dds/ddsi/q_lease.h"
|
#include "dds/ddsi/q_lease.h"
|
||||||
#include "dds/ddsi/q_log.h"
|
#include "dds/ddsi/q_log.h"
|
||||||
|
@ -49,7 +50,7 @@ void write_pmd_message_guid (struct q_globals * const gv, struct ddsi_guid *pp_g
|
||||||
{
|
{
|
||||||
struct thread_state1 * const ts1 = lookup_thread_state ();
|
struct thread_state1 * const ts1 = lookup_thread_state ();
|
||||||
thread_state_awake (ts1, gv);
|
thread_state_awake (ts1, gv);
|
||||||
struct participant *pp = ephash_lookup_participant_guid (gv->guid_hash, pp_guid);
|
struct participant *pp = entidx_lookup_participant_guid (gv->entity_index, pp_guid);
|
||||||
if (pp == NULL)
|
if (pp == NULL)
|
||||||
GVTRACE ("write_pmd_message("PGUIDFMT") - builtin pmd writer not found\n", PGUID (*pp_guid));
|
GVTRACE ("write_pmd_message("PGUIDFMT") - builtin pmd writer not found\n", PGUID (*pp_guid));
|
||||||
else
|
else
|
||||||
|
@ -127,7 +128,7 @@ void handle_pmd_message (const struct receiver_state *rst, nn_wctime_t timestamp
|
||||||
debug_print_rawdata (rst->gv, "", pmd->value, length);
|
debug_print_rawdata (rst->gv, "", pmd->value, length);
|
||||||
ppguid.prefix = p;
|
ppguid.prefix = p;
|
||||||
ppguid.entityid.u = NN_ENTITYID_PARTICIPANT;
|
ppguid.entityid.u = NN_ENTITYID_PARTICIPANT;
|
||||||
if ((proxypp = ephash_lookup_proxy_participant_guid (rst->gv->guid_hash, &ppguid)) == NULL)
|
if ((proxypp = entidx_lookup_proxy_participant_guid (rst->gv->entity_index, &ppguid)) == NULL)
|
||||||
RSTTRACE (" PPunknown");
|
RSTTRACE (" PPunknown");
|
||||||
else if (kind == PARTICIPANT_MESSAGE_DATA_KIND_MANUAL_LIVELINESS_UPDATE &&
|
else if (kind == PARTICIPANT_MESSAGE_DATA_KIND_MANUAL_LIVELINESS_UPDATE &&
|
||||||
(l = ddsrt_atomic_ldvoidp (&proxypp->minl_man)) != NULL)
|
(l = ddsrt_atomic_ldvoidp (&proxypp->minl_man)) != NULL)
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "dds/ddsi/q_transmit.h"
|
#include "dds/ddsi/q_transmit.h"
|
||||||
#include "dds/ddsi/q_misc.h"
|
#include "dds/ddsi/q_misc.h"
|
||||||
#include "dds/ddsi/ddsi_tkmap.h"
|
#include "dds/ddsi/ddsi_tkmap.h"
|
||||||
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/ddsi/ddsi_security_msg.h"
|
#include "dds/ddsi/ddsi_security_msg.h"
|
||||||
#include "dds/ddsi/ddsi_plist_generic.h"
|
#include "dds/ddsi/ddsi_plist_generic.h"
|
||||||
|
|
||||||
|
@ -183,7 +184,7 @@ write_crypto_exchange_message(
|
||||||
|
|
||||||
prd_guid.prefix = dst_pguid->prefix;
|
prd_guid.prefix = dst_pguid->prefix;
|
||||||
prd_guid.entityid.u = NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_READER;
|
prd_guid.entityid.u = NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_READER;
|
||||||
if ((prd = ephash_lookup_proxy_reader_guid (gv->guid_hash, &prd_guid)) == NULL)
|
if ((prd = entidx_lookup_proxy_reader_guid (gv->entity_index, &prd_guid)) == NULL)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "dds/ddsi/q_bswap.h"
|
#include "dds/ddsi/q_bswap.h"
|
||||||
#include "dds/ddsi/q_unused.h"
|
#include "dds/ddsi/q_unused.h"
|
||||||
#include "dds/ddsi/q_radmin.h"
|
#include "dds/ddsi/q_radmin.h"
|
||||||
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/ddsi/ddsi_security_omg.h"
|
#include "dds/ddsi/ddsi_security_omg.h"
|
||||||
#include "dds/ddsi/ddsi_sertopic.h"
|
#include "dds/ddsi/ddsi_sertopic.h"
|
||||||
|
|
||||||
|
@ -215,7 +216,7 @@ is_proxy_participant_deletion_allowed(
|
||||||
|
|
||||||
/* Not from a secure proxy writer.
|
/* Not from a secure proxy writer.
|
||||||
* Only allow deletion when proxy participant is not authenticated. */
|
* Only allow deletion when proxy participant is not authenticated. */
|
||||||
proxypp = ephash_lookup_proxy_participant_guid(gv->guid_hash, guid);
|
proxypp = entidx_lookup_proxy_participant_guid(gv->entity_index, guid);
|
||||||
if (!proxypp)
|
if (!proxypp)
|
||||||
{
|
{
|
||||||
GVLOGDISC (" unknown");
|
GVLOGDISC (" unknown");
|
||||||
|
@ -674,7 +675,7 @@ encode_datareader_submsg(
|
||||||
/* Only encode when needed. */
|
/* Only encode when needed. */
|
||||||
if (q_omg_security_enabled())
|
if (q_omg_security_enabled())
|
||||||
{
|
{
|
||||||
struct reader *rd = ephash_lookup_reader_guid(pwr->e.gv->guid_hash, rd_guid);
|
struct reader *rd = entidx_lookup_reader_guid(pwr->e.gv->entity_index, rd_guid);
|
||||||
if (rd)
|
if (rd)
|
||||||
{
|
{
|
||||||
if (q_omg_reader_is_submessage_protected(rd))
|
if (q_omg_reader_is_submessage_protected(rd))
|
||||||
|
@ -977,7 +978,7 @@ check_rtps_message_is_secure(
|
||||||
|
|
||||||
GVTRACE(" from "PGUIDFMT, PGUID(guid));
|
GVTRACE(" from "PGUIDFMT, PGUID(guid));
|
||||||
|
|
||||||
*proxypp = ephash_lookup_proxy_participant_guid(gv->guid_hash, &guid);
|
*proxypp = entidx_lookup_proxy_participant_guid(gv->entity_index, &guid);
|
||||||
if (*proxypp)
|
if (*proxypp)
|
||||||
{
|
{
|
||||||
if (q_omg_proxyparticipant_is_authenticated(*proxypp))
|
if (q_omg_proxyparticipant_is_authenticated(*proxypp))
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include "dds/ddsi/q_ddsi_discovery.h"
|
#include "dds/ddsi/q_ddsi_discovery.h"
|
||||||
|
|
||||||
#include "dds/ddsi/q_radmin.h"
|
#include "dds/ddsi/q_radmin.h"
|
||||||
#include "dds/ddsi/q_ephash.h"
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
#include "dds/ddsi/q_globals.h"
|
#include "dds/ddsi/q_globals.h"
|
||||||
#include "dds/ddsi/q_xmsg.h"
|
#include "dds/ddsi/q_xmsg.h"
|
||||||
|
@ -416,11 +416,11 @@ static unsigned pseudo_random_delay (const ddsi_guid_t *x, const ddsi_guid_t *y,
|
||||||
|
|
||||||
static void respond_to_spdp (const struct q_globals *gv, const ddsi_guid_t *dest_proxypp_guid)
|
static void respond_to_spdp (const struct q_globals *gv, const ddsi_guid_t *dest_proxypp_guid)
|
||||||
{
|
{
|
||||||
struct ephash_enum_participant est;
|
struct entidx_enum_participant est;
|
||||||
struct participant *pp;
|
struct participant *pp;
|
||||||
nn_mtime_t tnow = now_mt ();
|
nn_mtime_t tnow = now_mt ();
|
||||||
ephash_enum_participant_init (&est, gv->guid_hash);
|
entidx_enum_participant_init (&est, gv->entity_index);
|
||||||
while ((pp = ephash_enum_participant_next (&est)) != NULL)
|
while ((pp = entidx_enum_participant_next (&est)) != NULL)
|
||||||
{
|
{
|
||||||
/* delay_base has 32 bits, so delay_norm is approximately 1s max;
|
/* delay_base has 32 bits, so delay_norm is approximately 1s max;
|
||||||
delay_max <= 1s by gv.config checks */
|
delay_max <= 1s by gv.config checks */
|
||||||
|
@ -436,7 +436,7 @@ static void respond_to_spdp (const struct q_globals *gv, const ddsi_guid_t *dest
|
||||||
else
|
else
|
||||||
qxev_spdp (gv->xevents, tsched, &pp->e.guid, dest_proxypp_guid);
|
qxev_spdp (gv->xevents, tsched, &pp->e.guid, dest_proxypp_guid);
|
||||||
}
|
}
|
||||||
ephash_enum_participant_fini (&est);
|
entidx_enum_participant_fini (&est);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_SPDP_dead (const struct receiver_state *rst, ddsi_entityid_t pwr_entityid, nn_wctime_t timestamp, const nn_plist_t *datap, unsigned statusinfo)
|
static int handle_SPDP_dead (const struct receiver_state *rst, ddsi_entityid_t pwr_entityid, nn_wctime_t timestamp, const nn_plist_t *datap, unsigned statusinfo)
|
||||||
|
@ -494,28 +494,28 @@ static void allowmulticast_aware_add_to_addrset (const struct q_globals *gv, uin
|
||||||
add_to_addrset (gv, as, loc);
|
add_to_addrset (gv, as, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct proxy_participant *find_ddsi2_proxy_participant (const struct ephash *guid_hash, const ddsi_guid_t *ppguid)
|
static struct proxy_participant *find_ddsi2_proxy_participant (const struct entity_index *entidx, const ddsi_guid_t *ppguid)
|
||||||
{
|
{
|
||||||
struct ephash_enum_proxy_participant it;
|
struct entidx_enum_proxy_participant it;
|
||||||
struct proxy_participant *pp;
|
struct proxy_participant *pp;
|
||||||
ephash_enum_proxy_participant_init (&it, guid_hash);
|
entidx_enum_proxy_participant_init (&it, entidx);
|
||||||
while ((pp = ephash_enum_proxy_participant_next (&it)) != NULL)
|
while ((pp = entidx_enum_proxy_participant_next (&it)) != NULL)
|
||||||
{
|
{
|
||||||
if (vendor_is_eclipse_or_opensplice (pp->vendor) && pp->e.guid.prefix.u[0] == ppguid->prefix.u[0] && pp->is_ddsi2_pp)
|
if (vendor_is_eclipse_or_opensplice (pp->vendor) && pp->e.guid.prefix.u[0] == ppguid->prefix.u[0] && pp->is_ddsi2_pp)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ephash_enum_proxy_participant_fini (&it);
|
entidx_enum_proxy_participant_fini (&it);
|
||||||
return pp;
|
return pp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void make_participants_dependent_on_ddsi2 (struct q_globals *gv, const ddsi_guid_t *ddsi2guid, nn_wctime_t timestamp)
|
static void make_participants_dependent_on_ddsi2 (struct q_globals *gv, const ddsi_guid_t *ddsi2guid, nn_wctime_t timestamp)
|
||||||
{
|
{
|
||||||
struct ephash_enum_proxy_participant it;
|
struct entidx_enum_proxy_participant it;
|
||||||
struct proxy_participant *pp, *d2pp;
|
struct proxy_participant *pp, *d2pp;
|
||||||
if ((d2pp = ephash_lookup_proxy_participant_guid (gv->guid_hash, ddsi2guid)) == NULL)
|
if ((d2pp = entidx_lookup_proxy_participant_guid (gv->entity_index, ddsi2guid)) == NULL)
|
||||||
return;
|
return;
|
||||||
ephash_enum_proxy_participant_init (&it, gv->guid_hash);
|
entidx_enum_proxy_participant_init (&it, gv->entity_index);
|
||||||
while ((pp = ephash_enum_proxy_participant_next (&it)) != NULL)
|
while ((pp = entidx_enum_proxy_participant_next (&it)) != NULL)
|
||||||
{
|
{
|
||||||
if (vendor_is_eclipse_or_opensplice (pp->vendor) && pp->e.guid.prefix.u[0] == ddsi2guid->prefix.u[0] && !pp->is_ddsi2_pp)
|
if (vendor_is_eclipse_or_opensplice (pp->vendor) && pp->e.guid.prefix.u[0] == ddsi2guid->prefix.u[0] && !pp->is_ddsi2_pp)
|
||||||
{
|
{
|
||||||
|
@ -526,7 +526,7 @@ static void make_participants_dependent_on_ddsi2 (struct q_globals *gv, const dd
|
||||||
proxy_participant_reassign_lease (pp, d2pp->lease);
|
proxy_participant_reassign_lease (pp, d2pp->lease);
|
||||||
GVTRACE ("\n");
|
GVTRACE ("\n");
|
||||||
|
|
||||||
if (ephash_lookup_proxy_participant_guid (gv->guid_hash, ddsi2guid) == NULL)
|
if (entidx_lookup_proxy_participant_guid (gv->entity_index, ddsi2guid) == NULL)
|
||||||
{
|
{
|
||||||
/* If DDSI2 has been deleted here (i.e., very soon after
|
/* If DDSI2 has been deleted here (i.e., very soon after
|
||||||
having been created), we don't know whether pp will be
|
having been created), we don't know whether pp will be
|
||||||
|
@ -535,7 +535,7 @@ static void make_participants_dependent_on_ddsi2 (struct q_globals *gv, const dd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ephash_enum_proxy_participant_fini (&it);
|
entidx_enum_proxy_participant_fini (&it);
|
||||||
|
|
||||||
if (pp != NULL)
|
if (pp != NULL)
|
||||||
{
|
{
|
||||||
|
@ -614,7 +614,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
|
||||||
/* Do we know this GUID already? */
|
/* Do we know this GUID already? */
|
||||||
{
|
{
|
||||||
struct entity_common *existing_entity;
|
struct entity_common *existing_entity;
|
||||||
if ((existing_entity = ephash_lookup_guid_untyped (gv->guid_hash, &datap->participant_guid)) == NULL)
|
if ((existing_entity = entidx_lookup_guid_untyped (gv->entity_index, &datap->participant_guid)) == NULL)
|
||||||
{
|
{
|
||||||
/* Local SPDP packets may be looped back, and that can include ones
|
/* Local SPDP packets may be looped back, and that can include ones
|
||||||
for participants currently being deleted. The first thing that
|
for participants currently being deleted. The first thing that
|
||||||
|
@ -699,7 +699,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
|
||||||
the SPDP writer differs from the guid prefix of the new participant,
|
the SPDP writer differs from the guid prefix of the new participant,
|
||||||
we make it dependent on the writer's participant. See also the
|
we make it dependent on the writer's participant. See also the
|
||||||
lease expiration handling. Note that the entityid MUST be
|
lease expiration handling. Note that the entityid MUST be
|
||||||
NN_ENTITYID_PARTICIPANT or ephash_lookup will assert. So we only
|
NN_ENTITYID_PARTICIPANT or entidx_lookup will assert. So we only
|
||||||
zero the prefix. */
|
zero the prefix. */
|
||||||
privileged_pp_guid.prefix = rst->src_guid_prefix;
|
privileged_pp_guid.prefix = rst->src_guid_prefix;
|
||||||
privileged_pp_guid.entityid.u = NN_ENTITYID_PARTICIPANT;
|
privileged_pp_guid.entityid.u = NN_ENTITYID_PARTICIPANT;
|
||||||
|
@ -716,7 +716,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
|
||||||
/* Non-DDSI2 participants are made dependent on DDSI2 (but DDSI2
|
/* Non-DDSI2 participants are made dependent on DDSI2 (but DDSI2
|
||||||
itself need not be discovered yet) */
|
itself need not be discovered yet) */
|
||||||
struct proxy_participant *ddsi2;
|
struct proxy_participant *ddsi2;
|
||||||
if ((ddsi2 = find_ddsi2_proxy_participant (gv->guid_hash, &datap->participant_guid)) == NULL)
|
if ((ddsi2 = find_ddsi2_proxy_participant (gv->entity_index, &datap->participant_guid)) == NULL)
|
||||||
memset (&privileged_pp_guid.prefix, 0, sizeof (privileged_pp_guid.prefix));
|
memset (&privileged_pp_guid.prefix, 0, sizeof (privileged_pp_guid.prefix));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -835,7 +835,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
|
||||||
/* If we just created a participant dependent on DDSI2, make sure
|
/* If we just created a participant dependent on DDSI2, make sure
|
||||||
DDSI2 still exists. There is a risk of racing the lease expiry
|
DDSI2 still exists. There is a risk of racing the lease expiry
|
||||||
of DDSI2. */
|
of DDSI2. */
|
||||||
if (ephash_lookup_proxy_participant_guid (gv->guid_hash, &privileged_pp_guid) == NULL)
|
if (entidx_lookup_proxy_participant_guid (gv->entity_index, &privileged_pp_guid) == NULL)
|
||||||
{
|
{
|
||||||
GVLOGDISC ("make_participants_dependent_on_ddsi2: ddsi2 "PGUIDFMT" is no more, delete "PGUIDFMT"\n",
|
GVLOGDISC ("make_participants_dependent_on_ddsi2: ddsi2 "PGUIDFMT" is no more, delete "PGUIDFMT"\n",
|
||||||
PGUID (privileged_pp_guid), PGUID (datap->participant_guid));
|
PGUID (privileged_pp_guid), PGUID (datap->participant_guid));
|
||||||
|
@ -999,7 +999,7 @@ static int sedp_write_endpoint
|
||||||
the default. */
|
the default. */
|
||||||
if (!is_writer_entityid (epguid->entityid))
|
if (!is_writer_entityid (epguid->entityid))
|
||||||
{
|
{
|
||||||
const struct reader *rd = ephash_lookup_reader_guid (gv->guid_hash, epguid);
|
const struct reader *rd = entidx_lookup_reader_guid (gv->entity_index, epguid);
|
||||||
assert (rd);
|
assert (rd);
|
||||||
if (rd->favours_ssm)
|
if (rd->favours_ssm)
|
||||||
{
|
{
|
||||||
|
@ -1173,7 +1173,7 @@ static struct proxy_participant *implicitly_create_proxypp (struct q_globals *gv
|
||||||
readers or writers, only if remote ddsi2 is provably running
|
readers or writers, only if remote ddsi2 is provably running
|
||||||
with a minimal built-in endpoint set */
|
with a minimal built-in endpoint set */
|
||||||
struct proxy_participant *privpp;
|
struct proxy_participant *privpp;
|
||||||
if ((privpp = ephash_lookup_proxy_participant_guid (gv->guid_hash, &privguid)) == NULL) {
|
if ((privpp = entidx_lookup_proxy_participant_guid (gv->entity_index, &privguid)) == NULL) {
|
||||||
GVTRACE (" unknown-src-proxypp?\n");
|
GVTRACE (" unknown-src-proxypp?\n");
|
||||||
goto err;
|
goto err;
|
||||||
} else if (!privpp->is_ddsi2_pp) {
|
} else if (!privpp->is_ddsi2_pp) {
|
||||||
|
@ -1205,7 +1205,7 @@ static struct proxy_participant *implicitly_create_proxypp (struct q_globals *gv
|
||||||
|
|
||||||
err:
|
err:
|
||||||
nn_plist_fini (&pp_plist);
|
nn_plist_fini (&pp_plist);
|
||||||
return ephash_lookup_proxy_participant_guid (gv->guid_hash, ppguid);
|
return entidx_lookup_proxy_participant_guid (gv->entity_index, ppguid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_SEDP_alive (const struct receiver_state *rst, seqno_t seq, nn_plist_t *datap /* note: potentially modifies datap */, const ddsi_guid_prefix_t *src_guid_prefix, nn_vendorid_t vendorid, nn_wctime_t timestamp)
|
static void handle_SEDP_alive (const struct receiver_state *rst, seqno_t seq, nn_plist_t *datap /* note: potentially modifies datap */, const ddsi_guid_prefix_t *src_guid_prefix, nn_vendorid_t vendorid, nn_wctime_t timestamp)
|
||||||
|
@ -1235,7 +1235,7 @@ static void handle_SEDP_alive (const struct receiver_state *rst, seqno_t seq, nn
|
||||||
if (is_deleted_participant_guid (gv->deleted_participants, &ppguid, DPG_REMOTE))
|
if (is_deleted_participant_guid (gv->deleted_participants, &ppguid, DPG_REMOTE))
|
||||||
E (" local dead pp?\n", err);
|
E (" local dead pp?\n", err);
|
||||||
|
|
||||||
if (ephash_lookup_participant_guid (gv->guid_hash, &ppguid) != NULL)
|
if (entidx_lookup_participant_guid (gv->entity_index, &ppguid) != NULL)
|
||||||
E (" local pp?\n", err);
|
E (" local pp?\n", err);
|
||||||
|
|
||||||
if (is_builtin_entityid (datap->endpoint_guid.entityid, vendorid))
|
if (is_builtin_entityid (datap->endpoint_guid.entityid, vendorid))
|
||||||
|
@ -1245,7 +1245,7 @@ static void handle_SEDP_alive (const struct receiver_state *rst, seqno_t seq, nn
|
||||||
if (!(datap->qos.present & QP_TYPE_NAME))
|
if (!(datap->qos.present & QP_TYPE_NAME))
|
||||||
E (" no typename?\n", err);
|
E (" no typename?\n", err);
|
||||||
|
|
||||||
if ((pp = ephash_lookup_proxy_participant_guid (gv->guid_hash, &ppguid)) == NULL)
|
if ((pp = entidx_lookup_proxy_participant_guid (gv->entity_index, &ppguid)) == NULL)
|
||||||
{
|
{
|
||||||
GVLOGDISC (" unknown-proxypp");
|
GVLOGDISC (" unknown-proxypp");
|
||||||
if ((pp = implicitly_create_proxypp (gv, &ppguid, datap, src_guid_prefix, vendorid, timestamp, 0)) == NULL)
|
if ((pp = implicitly_create_proxypp (gv, &ppguid, datap, src_guid_prefix, vendorid, timestamp, 0)) == NULL)
|
||||||
|
@ -1287,11 +1287,11 @@ static void handle_SEDP_alive (const struct receiver_state *rst, seqno_t seq, nn
|
||||||
|
|
||||||
if (is_writer)
|
if (is_writer)
|
||||||
{
|
{
|
||||||
pwr = ephash_lookup_proxy_writer_guid (gv->guid_hash, &datap->endpoint_guid);
|
pwr = entidx_lookup_proxy_writer_guid (gv->entity_index, &datap->endpoint_guid);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prd = ephash_lookup_proxy_reader_guid (gv->guid_hash, &datap->endpoint_guid);
|
prd = entidx_lookup_proxy_reader_guid (gv->entity_index, &datap->endpoint_guid);
|
||||||
}
|
}
|
||||||
if (pwr || prd)
|
if (pwr || prd)
|
||||||
{
|
{
|
||||||
|
@ -1301,11 +1301,10 @@ static void handle_SEDP_alive (const struct receiver_state *rst, seqno_t seq, nn
|
||||||
GVLOGDISC (" known%s", vendor_is_cloud (vendorid) ? "-DS" : "");
|
GVLOGDISC (" known%s", vendor_is_cloud (vendorid) ? "-DS" : "");
|
||||||
if (vendor_is_cloud (vendorid) && pp->implicitly_created && memcmp(&pp->privileged_pp_guid.prefix, src_guid_prefix, sizeof(pp->privileged_pp_guid.prefix)) != 0)
|
if (vendor_is_cloud (vendorid) && pp->implicitly_created && memcmp(&pp->privileged_pp_guid.prefix, src_guid_prefix, sizeof(pp->privileged_pp_guid.prefix)) != 0)
|
||||||
{
|
{
|
||||||
nn_etime_t never = { T_NEVER };
|
|
||||||
GVLOGDISC (" "PGUIDFMT" attach-to-DS "PGUIDFMT, PGUID(pp->e.guid), PGUIDPREFIX(*src_guid_prefix), pp->privileged_pp_guid.entityid.u);
|
GVLOGDISC (" "PGUIDFMT" attach-to-DS "PGUIDFMT, PGUID(pp->e.guid), PGUIDPREFIX(*src_guid_prefix), pp->privileged_pp_guid.entityid.u);
|
||||||
ddsrt_mutex_lock (&pp->e.lock);
|
ddsrt_mutex_lock (&pp->e.lock);
|
||||||
pp->privileged_pp_guid.prefix = *src_guid_prefix;
|
pp->privileged_pp_guid.prefix = *src_guid_prefix;
|
||||||
lease_set_expiry(pp->lease, never);
|
lease_set_expiry(pp->lease, NN_ETIME_NEVER);
|
||||||
ddsrt_mutex_unlock (&pp->e.lock);
|
ddsrt_mutex_unlock (&pp->e.lock);
|
||||||
}
|
}
|
||||||
GVLOGDISC ("\n");
|
GVLOGDISC ("\n");
|
||||||
|
@ -1590,7 +1589,7 @@ static void handle_SEDP_CM (const struct receiver_state *rst, ddsi_entityid_t wr
|
||||||
GVWARNING ("SEDP_CM (vendor %u.%u): missing participant GUID\n", src.vendorid.id[0], src.vendorid.id[1]);
|
GVWARNING ("SEDP_CM (vendor %u.%u): missing participant GUID\n", src.vendorid.id[0], src.vendorid.id[1]);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((proxypp = ephash_lookup_proxy_participant_guid (gv->guid_hash, &decoded_data.participant_guid)) == NULL)
|
if ((proxypp = entidx_lookup_proxy_participant_guid (gv->entity_index, &decoded_data.participant_guid)) == NULL)
|
||||||
proxypp = implicitly_create_proxypp (gv, &decoded_data.participant_guid, &decoded_data, &rst->src_guid_prefix, rst->vendor, timestamp, 0);
|
proxypp = implicitly_create_proxypp (gv, &decoded_data.participant_guid, &decoded_data, &rst->src_guid_prefix, rst->vendor, timestamp, 0);
|
||||||
if (proxypp != NULL)
|
if (proxypp != NULL)
|
||||||
update_proxy_participant_plist (proxypp, 0, &decoded_data, UPD_PROXYPP_CM, timestamp);
|
update_proxy_participant_plist (proxypp, 0, &decoded_data, UPD_PROXYPP_CM, timestamp);
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include "dds/ddsi/q_misc.h"
|
#include "dds/ddsi/q_misc.h"
|
||||||
#include "dds/ddsi/q_log.h"
|
#include "dds/ddsi/q_log.h"
|
||||||
#include "dds/ddsi/q_plist.h"
|
#include "dds/ddsi/q_plist.h"
|
||||||
#include "dds/ddsi/q_ephash.h"
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/ddsi/q_globals.h"
|
#include "dds/ddsi/q_globals.h"
|
||||||
#include "dds/ddsi/q_addrset.h"
|
#include "dds/ddsi/q_addrset.h"
|
||||||
#include "dds/ddsi/q_radmin.h"
|
#include "dds/ddsi/q_radmin.h"
|
||||||
|
@ -144,22 +144,22 @@ static int print_proxy_endpoint_common (ddsi_tran_conn_t conn, const char *label
|
||||||
|
|
||||||
static int print_participants (struct thread_state1 * const ts1, struct q_globals *gv, ddsi_tran_conn_t conn)
|
static int print_participants (struct thread_state1 * const ts1, struct q_globals *gv, ddsi_tran_conn_t conn)
|
||||||
{
|
{
|
||||||
struct ephash_enum_participant e;
|
struct entidx_enum_participant e;
|
||||||
struct participant *p;
|
struct participant *p;
|
||||||
int x = 0;
|
int x = 0;
|
||||||
thread_state_awake_fixed_domain (ts1);
|
thread_state_awake_fixed_domain (ts1);
|
||||||
ephash_enum_participant_init (&e, gv->guid_hash);
|
entidx_enum_participant_init (&e, gv->entity_index);
|
||||||
while ((p = ephash_enum_participant_next (&e)) != NULL)
|
while ((p = entidx_enum_participant_next (&e)) != NULL)
|
||||||
{
|
{
|
||||||
ddsrt_mutex_lock (&p->e.lock);
|
ddsrt_mutex_lock (&p->e.lock);
|
||||||
x += cpf (conn, "pp "PGUIDFMT" %s%s\n", PGUID (p->e.guid), p->e.name, p->is_ddsi2_pp ? " [ddsi2]" : "");
|
x += cpf (conn, "pp "PGUIDFMT" %s%s\n", PGUID (p->e.guid), p->e.name, p->is_ddsi2_pp ? " [ddsi2]" : "");
|
||||||
ddsrt_mutex_unlock (&p->e.lock);
|
ddsrt_mutex_unlock (&p->e.lock);
|
||||||
|
|
||||||
{
|
{
|
||||||
struct ephash_enum_reader er;
|
struct entidx_enum_reader er;
|
||||||
struct reader *r;
|
struct reader *r;
|
||||||
ephash_enum_reader_init (&er, gv->guid_hash);
|
entidx_enum_reader_init (&er, gv->entity_index);
|
||||||
while ((r = ephash_enum_reader_next (&er)) != NULL)
|
while ((r = entidx_enum_reader_next (&er)) != NULL)
|
||||||
{
|
{
|
||||||
ddsrt_avl_iter_t writ;
|
ddsrt_avl_iter_t writ;
|
||||||
struct rd_pwr_match *m;
|
struct rd_pwr_match *m;
|
||||||
|
@ -174,14 +174,14 @@ static int print_participants (struct thread_state1 * const ts1, struct q_global
|
||||||
x += cpf (conn, " pwr "PGUIDFMT"\n", PGUID (m->pwr_guid));
|
x += cpf (conn, " pwr "PGUIDFMT"\n", PGUID (m->pwr_guid));
|
||||||
ddsrt_mutex_unlock (&r->e.lock);
|
ddsrt_mutex_unlock (&r->e.lock);
|
||||||
}
|
}
|
||||||
ephash_enum_reader_fini (&er);
|
entidx_enum_reader_fini (&er);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
struct ephash_enum_writer ew;
|
struct entidx_enum_writer ew;
|
||||||
struct writer *w;
|
struct writer *w;
|
||||||
ephash_enum_writer_init (&ew, gv->guid_hash);
|
entidx_enum_writer_init (&ew, gv->entity_index);
|
||||||
while ((w = ephash_enum_writer_next (&ew)) != NULL)
|
while ((w = entidx_enum_writer_next (&ew)) != NULL)
|
||||||
{
|
{
|
||||||
ddsrt_avl_iter_t rdit;
|
ddsrt_avl_iter_t rdit;
|
||||||
struct wr_prd_match *m;
|
struct wr_prd_match *m;
|
||||||
|
@ -219,22 +219,22 @@ static int print_participants (struct thread_state1 * const ts1, struct q_global
|
||||||
}
|
}
|
||||||
ddsrt_mutex_unlock (&w->e.lock);
|
ddsrt_mutex_unlock (&w->e.lock);
|
||||||
}
|
}
|
||||||
ephash_enum_writer_fini (&ew);
|
entidx_enum_writer_fini (&ew);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ephash_enum_participant_fini (&e);
|
entidx_enum_participant_fini (&e);
|
||||||
thread_state_asleep (ts1);
|
thread_state_asleep (ts1);
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int print_proxy_participants (struct thread_state1 * const ts1, struct q_globals *gv, ddsi_tran_conn_t conn)
|
static int print_proxy_participants (struct thread_state1 * const ts1, struct q_globals *gv, ddsi_tran_conn_t conn)
|
||||||
{
|
{
|
||||||
struct ephash_enum_proxy_participant e;
|
struct entidx_enum_proxy_participant e;
|
||||||
struct proxy_participant *p;
|
struct proxy_participant *p;
|
||||||
int x = 0;
|
int x = 0;
|
||||||
thread_state_awake_fixed_domain (ts1);
|
thread_state_awake_fixed_domain (ts1);
|
||||||
ephash_enum_proxy_participant_init (&e, gv->guid_hash);
|
entidx_enum_proxy_participant_init (&e, gv->entity_index);
|
||||||
while ((p = ephash_enum_proxy_participant_next (&e)) != NULL)
|
while ((p = entidx_enum_proxy_participant_next (&e)) != NULL)
|
||||||
{
|
{
|
||||||
ddsrt_mutex_lock (&p->e.lock);
|
ddsrt_mutex_lock (&p->e.lock);
|
||||||
x += cpf (conn, "proxypp "PGUIDFMT"%s\n", PGUID (p->e.guid), p->is_ddsi2_pp ? " [ddsi2]" : "");
|
x += cpf (conn, "proxypp "PGUIDFMT"%s\n", PGUID (p->e.guid), p->is_ddsi2_pp ? " [ddsi2]" : "");
|
||||||
|
@ -243,10 +243,10 @@ static int print_proxy_participants (struct thread_state1 * const ts1, struct q_
|
||||||
x += print_addrset (conn, " meta", p->as_default, "\n");
|
x += print_addrset (conn, " meta", p->as_default, "\n");
|
||||||
|
|
||||||
{
|
{
|
||||||
struct ephash_enum_proxy_reader er;
|
struct entidx_enum_proxy_reader er;
|
||||||
struct proxy_reader *r;
|
struct proxy_reader *r;
|
||||||
ephash_enum_proxy_reader_init (&er, gv->guid_hash);
|
entidx_enum_proxy_reader_init (&er, gv->entity_index);
|
||||||
while ((r = ephash_enum_proxy_reader_next (&er)) != NULL)
|
while ((r = entidx_enum_proxy_reader_next (&er)) != NULL)
|
||||||
{
|
{
|
||||||
ddsrt_avl_iter_t writ;
|
ddsrt_avl_iter_t writ;
|
||||||
struct prd_wr_match *m;
|
struct prd_wr_match *m;
|
||||||
|
@ -258,14 +258,14 @@ static int print_proxy_participants (struct thread_state1 * const ts1, struct q_
|
||||||
x += cpf (conn, " wr "PGUIDFMT"\n", PGUID (m->wr_guid));
|
x += cpf (conn, " wr "PGUIDFMT"\n", PGUID (m->wr_guid));
|
||||||
ddsrt_mutex_unlock (&r->e.lock);
|
ddsrt_mutex_unlock (&r->e.lock);
|
||||||
}
|
}
|
||||||
ephash_enum_proxy_reader_fini (&er);
|
entidx_enum_proxy_reader_fini (&er);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
struct ephash_enum_proxy_writer ew;
|
struct entidx_enum_proxy_writer ew;
|
||||||
struct proxy_writer *w;
|
struct proxy_writer *w;
|
||||||
ephash_enum_proxy_writer_init (&ew, gv->guid_hash);
|
entidx_enum_proxy_writer_init (&ew, gv->entity_index);
|
||||||
while ((w = ephash_enum_proxy_writer_next (&ew)) != NULL)
|
while ((w = entidx_enum_proxy_writer_next (&ew)) != NULL)
|
||||||
{
|
{
|
||||||
ddsrt_avl_iter_t rdit;
|
ddsrt_avl_iter_t rdit;
|
||||||
struct pwr_rd_match *m;
|
struct pwr_rd_match *m;
|
||||||
|
@ -292,10 +292,10 @@ static int print_proxy_participants (struct thread_state1 * const ts1, struct q_
|
||||||
}
|
}
|
||||||
ddsrt_mutex_unlock (&w->e.lock);
|
ddsrt_mutex_unlock (&w->e.lock);
|
||||||
}
|
}
|
||||||
ephash_enum_proxy_writer_fini (&ew);
|
entidx_enum_proxy_writer_fini (&ew);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ephash_enum_proxy_participant_fini (&e);
|
entidx_enum_proxy_participant_fini (&e);
|
||||||
thread_state_asleep (ts1);
|
thread_state_asleep (ts1);
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include "dds/ddsi/q_plist.h"
|
#include "dds/ddsi/q_plist.h"
|
||||||
#include "dds/ddsi/q_lease.h"
|
#include "dds/ddsi/q_lease.h"
|
||||||
#include "dds/ddsi/q_qosmatch.h"
|
#include "dds/ddsi/q_qosmatch.h"
|
||||||
#include "dds/ddsi/q_ephash.h"
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/ddsi/q_globals.h"
|
#include "dds/ddsi/q_globals.h"
|
||||||
#include "dds/ddsi/q_bswap.h"
|
#include "dds/ddsi/q_bswap.h"
|
||||||
#include "dds/ddsi/q_addrset.h"
|
#include "dds/ddsi/q_addrset.h"
|
||||||
|
@ -317,12 +317,21 @@ nn_vendorid_t get_entity_vendorid (const struct entity_common *e)
|
||||||
return NN_VENDORID_UNKNOWN;
|
return NN_VENDORID_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ddsi_make_writer_info(struct ddsi_writer_info *wrinfo, const struct entity_common *e, const struct dds_qos *xqos)
|
void ddsi_make_writer_info(struct ddsi_writer_info *wrinfo, const struct entity_common *e, const struct dds_qos *xqos, uint32_t statusinfo)
|
||||||
{
|
{
|
||||||
|
#ifndef DDSI_INCLUDE_LIFESPAN
|
||||||
|
DDSRT_UNUSED_ARG (statusinfo);
|
||||||
|
#endif
|
||||||
wrinfo->guid = e->guid;
|
wrinfo->guid = e->guid;
|
||||||
wrinfo->ownership_strength = xqos->ownership_strength.value;
|
wrinfo->ownership_strength = xqos->ownership_strength.value;
|
||||||
wrinfo->auto_dispose = xqos->writer_data_lifecycle.autodispose_unregistered_instances;
|
wrinfo->auto_dispose = xqos->writer_data_lifecycle.autodispose_unregistered_instances;
|
||||||
wrinfo->iid = e->iid;
|
wrinfo->iid = e->iid;
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
if (xqos->lifespan.duration != DDS_INFINITY && (statusinfo & (NN_STATUSINFO_UNREGISTER | NN_STATUSINFO_DISPOSE)) == 0)
|
||||||
|
wrinfo->lifespan_exp = add_duration_to_mtime(now_mt(), xqos->lifespan.duration);
|
||||||
|
else
|
||||||
|
wrinfo->lifespan_exp = NN_MTIME_NEVER;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DELETED PARTICIPANTS --------------------------------------------- */
|
/* DELETED PARTICIPANTS --------------------------------------------- */
|
||||||
|
@ -485,7 +494,7 @@ static void pp_release_entityid(struct participant *pp, ddsi_entityid_t id)
|
||||||
|
|
||||||
static void force_as_disc_address(struct q_globals *gv, const ddsi_guid_t *subguid)
|
static void force_as_disc_address(struct q_globals *gv, const ddsi_guid_t *subguid)
|
||||||
{
|
{
|
||||||
struct writer *wr = ephash_lookup_writer_guid (gv->guid_hash, subguid);
|
struct writer *wr = entidx_lookup_writer_guid (gv->entity_index, subguid);
|
||||||
assert (wr != NULL);
|
assert (wr != NULL);
|
||||||
ddsrt_mutex_lock (&wr->e.lock);
|
ddsrt_mutex_lock (&wr->e.lock);
|
||||||
unref_addrset (wr->as);
|
unref_addrset (wr->as);
|
||||||
|
@ -579,7 +588,7 @@ dds_return_t new_participant_guid (const ddsi_guid_t *ppguid, struct q_globals *
|
||||||
/* Participant may not exist yet, but this test is imprecise: if it
|
/* Participant may not exist yet, but this test is imprecise: if it
|
||||||
used to exist, but is currently being deleted and we're trying to
|
used to exist, but is currently being deleted and we're trying to
|
||||||
recreate it. */
|
recreate it. */
|
||||||
if (ephash_lookup_participant_guid (gv->guid_hash, ppguid) != NULL)
|
if (entidx_lookup_participant_guid (gv->entity_index, ppguid) != NULL)
|
||||||
return DDS_RETCODE_PRECONDITION_NOT_MET;
|
return DDS_RETCODE_PRECONDITION_NOT_MET;
|
||||||
|
|
||||||
if (gv->config.max_participants == 0)
|
if (gv->config.max_participants == 0)
|
||||||
|
@ -697,7 +706,7 @@ dds_return_t new_participant_guid (const ddsi_guid_t *ppguid, struct q_globals *
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make it globally visible, else the endpoint matching won't work. */
|
/* Make it globally visible, else the endpoint matching won't work. */
|
||||||
ephash_insert_participant_guid (gv->guid_hash, pp);
|
entidx_insert_participant_guid (gv->entity_index, pp);
|
||||||
|
|
||||||
/* SEDP writers: */
|
/* SEDP writers: */
|
||||||
if (!(flags & RTPS_PF_NO_BUILTIN_WRITERS))
|
if (!(flags & RTPS_PF_NO_BUILTIN_WRITERS))
|
||||||
|
@ -990,7 +999,7 @@ static void unref_participant (struct participant *pp, const struct ddsi_guid *g
|
||||||
The conditional execution of some of this is so we can use
|
The conditional execution of some of this is so we can use
|
||||||
unref_participant() for some of the error handling in
|
unref_participant() for some of the error handling in
|
||||||
new_participant(). Non-existent built-in endpoints can't be
|
new_participant(). Non-existent built-in endpoints can't be
|
||||||
found in guid_hash and are simply ignored. */
|
found in entity_index and are simply ignored. */
|
||||||
pp->builtins_deleted = 1;
|
pp->builtins_deleted = 1;
|
||||||
ddsrt_mutex_unlock (&pp->refc_lock);
|
ddsrt_mutex_unlock (&pp->refc_lock);
|
||||||
|
|
||||||
|
@ -1086,11 +1095,11 @@ dds_return_t delete_participant (struct q_globals *gv, const struct ddsi_guid *p
|
||||||
{
|
{
|
||||||
struct participant *pp;
|
struct participant *pp;
|
||||||
GVLOGDISC ("delete_participant("PGUIDFMT")\n", PGUID (*ppguid));
|
GVLOGDISC ("delete_participant("PGUIDFMT")\n", PGUID (*ppguid));
|
||||||
if ((pp = ephash_lookup_participant_guid (gv->guid_hash, ppguid)) == NULL)
|
if ((pp = entidx_lookup_participant_guid (gv->entity_index, ppguid)) == NULL)
|
||||||
return DDS_RETCODE_BAD_PARAMETER;
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
builtintopic_write (gv->builtin_topic_interface, &pp->e, now(), false);
|
builtintopic_write (gv->builtin_topic_interface, &pp->e, now(), false);
|
||||||
remember_deleted_participant_guid (gv->deleted_participants, &pp->e.guid);
|
remember_deleted_participant_guid (gv->deleted_participants, &pp->e.guid);
|
||||||
ephash_remove_participant_guid (gv->guid_hash, pp);
|
entidx_remove_participant_guid (gv->entity_index, pp);
|
||||||
gcreq_participant (pp);
|
gcreq_participant (pp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1179,7 +1188,7 @@ struct writer *get_builtin_writer (const struct participant *pp, unsigned entity
|
||||||
bwr_guid.entityid.u = entityid;
|
bwr_guid.entityid.u = entityid;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ephash_lookup_writer_guid (pp->e.gv->guid_hash, &bwr_guid);
|
return entidx_lookup_writer_guid (pp->e.gv->entity_index, &bwr_guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
dds_duration_t pp_get_pmd_interval (struct participant *pp)
|
dds_duration_t pp_get_pmd_interval (struct participant *pp)
|
||||||
|
@ -1234,7 +1243,7 @@ static int rebuild_compare_locs(const void *va, const void *vb)
|
||||||
static struct addrset *rebuild_make_all_addrs (int *nreaders, struct writer *wr)
|
static struct addrset *rebuild_make_all_addrs (int *nreaders, struct writer *wr)
|
||||||
{
|
{
|
||||||
struct addrset *all_addrs = new_addrset();
|
struct addrset *all_addrs = new_addrset();
|
||||||
struct ephash *gh = wr->e.gv->guid_hash;
|
struct entity_index *gh = wr->e.gv->entity_index;
|
||||||
struct wr_prd_match *m;
|
struct wr_prd_match *m;
|
||||||
ddsrt_avl_iter_t it;
|
ddsrt_avl_iter_t it;
|
||||||
#ifdef DDSI_INCLUDE_SSM
|
#ifdef DDSI_INCLUDE_SSM
|
||||||
|
@ -1245,7 +1254,7 @@ static struct addrset *rebuild_make_all_addrs (int *nreaders, struct writer *wr)
|
||||||
for (m = ddsrt_avl_iter_first (&wr_readers_treedef, &wr->readers, &it); m; m = ddsrt_avl_iter_next (&it))
|
for (m = ddsrt_avl_iter_first (&wr_readers_treedef, &wr->readers, &it); m; m = ddsrt_avl_iter_next (&it))
|
||||||
{
|
{
|
||||||
struct proxy_reader *prd;
|
struct proxy_reader *prd;
|
||||||
if ((prd = ephash_lookup_proxy_reader_guid (gh, &m->prd_guid)) == NULL)
|
if ((prd = entidx_lookup_proxy_reader_guid (gh, &m->prd_guid)) == NULL)
|
||||||
continue;
|
continue;
|
||||||
(*nreaders)++;
|
(*nreaders)++;
|
||||||
copy_addrset_into_addrset(wr->e.gv, all_addrs, prd->c.as);
|
copy_addrset_into_addrset(wr->e.gv, all_addrs, prd->c.as);
|
||||||
|
@ -1294,7 +1303,7 @@ static void rebuild_make_locs(const struct ddsrt_log_cfg *logcfg, int *p_nlocs,
|
||||||
static void rebuild_make_covered(int8_t **covered, const struct writer *wr, int *nreaders, int nlocs, const nn_locator_t *locs)
|
static void rebuild_make_covered(int8_t **covered, const struct writer *wr, int *nreaders, int nlocs, const nn_locator_t *locs)
|
||||||
{
|
{
|
||||||
struct rebuild_flatten_locs_arg flarg;
|
struct rebuild_flatten_locs_arg flarg;
|
||||||
struct ephash *gh = wr->e.gv->guid_hash;
|
struct entity_index *gh = wr->e.gv->entity_index;
|
||||||
struct wr_prd_match *m;
|
struct wr_prd_match *m;
|
||||||
ddsrt_avl_iter_t it;
|
ddsrt_avl_iter_t it;
|
||||||
int rdidx, i, j;
|
int rdidx, i, j;
|
||||||
|
@ -1310,7 +1319,7 @@ static void rebuild_make_covered(int8_t **covered, const struct writer *wr, int
|
||||||
{
|
{
|
||||||
struct proxy_reader *prd;
|
struct proxy_reader *prd;
|
||||||
struct addrset *ass[] = { NULL, NULL, NULL };
|
struct addrset *ass[] = { NULL, NULL, NULL };
|
||||||
if ((prd = ephash_lookup_proxy_reader_guid (gh, &m->prd_guid)) == NULL)
|
if ((prd = entidx_lookup_proxy_reader_guid (gh, &m->prd_guid)) == NULL)
|
||||||
continue;
|
continue;
|
||||||
ass[0] = prd->c.as;
|
ass[0] = prd->c.as;
|
||||||
#ifdef DDSI_INCLUDE_SSM
|
#ifdef DDSI_INCLUDE_SSM
|
||||||
|
@ -1511,12 +1520,12 @@ static void rebuild_writer_addrset (struct writer *wr)
|
||||||
|
|
||||||
void rebuild_or_clear_writer_addrsets (struct q_globals *gv, int rebuild)
|
void rebuild_or_clear_writer_addrsets (struct q_globals *gv, int rebuild)
|
||||||
{
|
{
|
||||||
struct ephash_enum_writer est;
|
struct entidx_enum_writer est;
|
||||||
struct writer *wr;
|
struct writer *wr;
|
||||||
struct addrset *empty = rebuild ? NULL : new_addrset();
|
struct addrset *empty = rebuild ? NULL : new_addrset();
|
||||||
GVLOGDISC ("rebuild_or_delete_writer_addrsets(%d)\n", rebuild);
|
GVLOGDISC ("rebuild_or_delete_writer_addrsets(%d)\n", rebuild);
|
||||||
ephash_enum_writer_init (&est, gv->guid_hash);
|
entidx_enum_writer_init (&est, gv->entity_index);
|
||||||
while ((wr = ephash_enum_writer_next (&est)) != NULL)
|
while ((wr = entidx_enum_writer_next (&est)) != NULL)
|
||||||
{
|
{
|
||||||
ddsrt_mutex_lock (&wr->e.lock);
|
ddsrt_mutex_lock (&wr->e.lock);
|
||||||
if (wr->e.guid.entityid.u != NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER)
|
if (wr->e.guid.entityid.u != NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER)
|
||||||
|
@ -1539,7 +1548,7 @@ void rebuild_or_clear_writer_addrsets (struct q_globals *gv, int rebuild)
|
||||||
}
|
}
|
||||||
ddsrt_mutex_unlock (&wr->e.lock);
|
ddsrt_mutex_unlock (&wr->e.lock);
|
||||||
}
|
}
|
||||||
ephash_enum_writer_fini (&est);
|
entidx_enum_writer_fini (&est);
|
||||||
unref_addrset(empty);
|
unref_addrset(empty);
|
||||||
GVLOGDISC ("rebuild_or_delete_writer_addrsets(%d) done\n", rebuild);
|
GVLOGDISC ("rebuild_or_delete_writer_addrsets(%d) done\n", rebuild);
|
||||||
}
|
}
|
||||||
|
@ -1614,7 +1623,7 @@ static void proxy_writer_get_alive_state (struct proxy_writer *pwr, struct proxy
|
||||||
static void writer_drop_connection (const struct ddsi_guid *wr_guid, const struct proxy_reader *prd)
|
static void writer_drop_connection (const struct ddsi_guid *wr_guid, const struct proxy_reader *prd)
|
||||||
{
|
{
|
||||||
struct writer *wr;
|
struct writer *wr;
|
||||||
if ((wr = ephash_lookup_writer_guid (prd->e.gv->guid_hash, wr_guid)) != NULL)
|
if ((wr = entidx_lookup_writer_guid (prd->e.gv->entity_index, wr_guid)) != NULL)
|
||||||
{
|
{
|
||||||
struct whc_node *deferred_free_list = NULL;
|
struct whc_node *deferred_free_list = NULL;
|
||||||
struct wr_prd_match *m;
|
struct wr_prd_match *m;
|
||||||
|
@ -1645,7 +1654,7 @@ static void writer_drop_local_connection (const struct ddsi_guid *wr_guid, struc
|
||||||
{
|
{
|
||||||
/* Only called by gc_delete_reader, so we actually have a reader pointer */
|
/* Only called by gc_delete_reader, so we actually have a reader pointer */
|
||||||
struct writer *wr;
|
struct writer *wr;
|
||||||
if ((wr = ephash_lookup_writer_guid (rd->e.gv->guid_hash, wr_guid)) != NULL)
|
if ((wr = entidx_lookup_writer_guid (rd->e.gv->entity_index, wr_guid)) != NULL)
|
||||||
{
|
{
|
||||||
struct wr_rd_match *m;
|
struct wr_rd_match *m;
|
||||||
|
|
||||||
|
@ -1689,7 +1698,7 @@ static void reader_update_notify_pwr_alive_state (struct reader *rd, const struc
|
||||||
if (delta < 0 && rd->rhc)
|
if (delta < 0 && rd->rhc)
|
||||||
{
|
{
|
||||||
struct ddsi_writer_info wrinfo;
|
struct ddsi_writer_info wrinfo;
|
||||||
ddsi_make_writer_info (&wrinfo, &pwr->e, pwr->c.xqos);
|
ddsi_make_writer_info (&wrinfo, &pwr->e, pwr->c.xqos, NN_STATUSINFO_UNREGISTER);
|
||||||
ddsi_rhc_unregister_wr (rd->rhc, &wrinfo);
|
ddsi_rhc_unregister_wr (rd->rhc, &wrinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1713,14 +1722,14 @@ static void reader_update_notify_pwr_alive_state (struct reader *rd, const struc
|
||||||
static void reader_update_notify_pwr_alive_state_guid (const struct ddsi_guid *rd_guid, const struct proxy_writer *pwr, const struct proxy_writer_alive_state *alive_state)
|
static void reader_update_notify_pwr_alive_state_guid (const struct ddsi_guid *rd_guid, const struct proxy_writer *pwr, const struct proxy_writer_alive_state *alive_state)
|
||||||
{
|
{
|
||||||
struct reader *rd;
|
struct reader *rd;
|
||||||
if ((rd = ephash_lookup_reader_guid (pwr->e.gv->guid_hash, rd_guid)) != NULL)
|
if ((rd = entidx_lookup_reader_guid (pwr->e.gv->entity_index, rd_guid)) != NULL)
|
||||||
reader_update_notify_pwr_alive_state (rd, pwr, alive_state);
|
reader_update_notify_pwr_alive_state (rd, pwr, alive_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reader_drop_connection (const struct ddsi_guid *rd_guid, const struct proxy_writer *pwr)
|
static void reader_drop_connection (const struct ddsi_guid *rd_guid, const struct proxy_writer *pwr)
|
||||||
{
|
{
|
||||||
struct reader *rd;
|
struct reader *rd;
|
||||||
if ((rd = ephash_lookup_reader_guid (pwr->e.gv->guid_hash, rd_guid)) != NULL)
|
if ((rd = entidx_lookup_reader_guid (pwr->e.gv->entity_index, rd_guid)) != NULL)
|
||||||
{
|
{
|
||||||
struct rd_pwr_match *m;
|
struct rd_pwr_match *m;
|
||||||
ddsrt_mutex_lock (&rd->e.lock);
|
ddsrt_mutex_lock (&rd->e.lock);
|
||||||
|
@ -1732,7 +1741,7 @@ static void reader_drop_connection (const struct ddsi_guid *rd_guid, const struc
|
||||||
if (rd->rhc)
|
if (rd->rhc)
|
||||||
{
|
{
|
||||||
struct ddsi_writer_info wrinfo;
|
struct ddsi_writer_info wrinfo;
|
||||||
ddsi_make_writer_info (&wrinfo, &pwr->e, pwr->c.xqos);
|
ddsi_make_writer_info (&wrinfo, &pwr->e, pwr->c.xqos, NN_STATUSINFO_UNREGISTER);
|
||||||
ddsi_rhc_unregister_wr (rd->rhc, &wrinfo);
|
ddsi_rhc_unregister_wr (rd->rhc, &wrinfo);
|
||||||
}
|
}
|
||||||
if (rd->status_cb)
|
if (rd->status_cb)
|
||||||
|
@ -1756,7 +1765,7 @@ static void reader_drop_connection (const struct ddsi_guid *rd_guid, const struc
|
||||||
static void reader_drop_local_connection (const struct ddsi_guid *rd_guid, const struct writer *wr)
|
static void reader_drop_local_connection (const struct ddsi_guid *rd_guid, const struct writer *wr)
|
||||||
{
|
{
|
||||||
struct reader *rd;
|
struct reader *rd;
|
||||||
if ((rd = ephash_lookup_reader_guid (wr->e.gv->guid_hash, rd_guid)) != NULL)
|
if ((rd = entidx_lookup_reader_guid (wr->e.gv->entity_index, rd_guid)) != NULL)
|
||||||
{
|
{
|
||||||
struct rd_wr_match *m;
|
struct rd_wr_match *m;
|
||||||
ddsrt_mutex_lock (&rd->e.lock);
|
ddsrt_mutex_lock (&rd->e.lock);
|
||||||
|
@ -1769,7 +1778,7 @@ static void reader_drop_local_connection (const struct ddsi_guid *rd_guid, const
|
||||||
{
|
{
|
||||||
/* FIXME: */
|
/* FIXME: */
|
||||||
struct ddsi_writer_info wrinfo;
|
struct ddsi_writer_info wrinfo;
|
||||||
ddsi_make_writer_info (&wrinfo, &wr->e, wr->xqos);
|
ddsi_make_writer_info (&wrinfo, &wr->e, wr->xqos, NN_STATUSINFO_UNREGISTER);
|
||||||
ddsi_rhc_unregister_wr (rd->rhc, &wrinfo);
|
ddsi_rhc_unregister_wr (rd->rhc, &wrinfo);
|
||||||
}
|
}
|
||||||
if (rd->status_cb)
|
if (rd->status_cb)
|
||||||
|
@ -1790,14 +1799,14 @@ static void reader_drop_local_connection (const struct ddsi_guid *rd_guid, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_reader_init_acknack_count (const ddsrt_log_cfg_t *logcfg, const struct ephash *guid_hash, const struct ddsi_guid *rd_guid, nn_count_t count)
|
static void update_reader_init_acknack_count (const ddsrt_log_cfg_t *logcfg, const struct entity_index *entidx, const struct ddsi_guid *rd_guid, nn_count_t count)
|
||||||
{
|
{
|
||||||
struct reader *rd;
|
struct reader *rd;
|
||||||
|
|
||||||
/* Update the initial acknack sequence number for the reader. See
|
/* Update the initial acknack sequence number for the reader. See
|
||||||
also reader_add_connection(). */
|
also reader_add_connection(). */
|
||||||
DDS_CLOG (DDS_LC_DISCOVERY, logcfg, "update_reader_init_acknack_count ("PGUIDFMT", %"PRId32"): ", PGUID (*rd_guid), count);
|
DDS_CLOG (DDS_LC_DISCOVERY, logcfg, "update_reader_init_acknack_count ("PGUIDFMT", %"PRId32"): ", PGUID (*rd_guid), count);
|
||||||
if ((rd = ephash_lookup_reader_guid (guid_hash, rd_guid)) != NULL)
|
if ((rd = entidx_lookup_reader_guid (entidx, rd_guid)) != NULL)
|
||||||
{
|
{
|
||||||
ddsrt_mutex_lock (&rd->e.lock);
|
ddsrt_mutex_lock (&rd->e.lock);
|
||||||
DDS_CLOG (DDS_LC_DISCOVERY, logcfg, "%"PRId32" -> ", rd->init_acknack_count);
|
DDS_CLOG (DDS_LC_DISCOVERY, logcfg, "%"PRId32" -> ", rd->init_acknack_count);
|
||||||
|
@ -1816,7 +1825,7 @@ static void proxy_writer_drop_connection (const struct ddsi_guid *pwr_guid, stru
|
||||||
{
|
{
|
||||||
/* Only called by gc_delete_reader, so we actually have a reader pointer */
|
/* Only called by gc_delete_reader, so we actually have a reader pointer */
|
||||||
struct proxy_writer *pwr;
|
struct proxy_writer *pwr;
|
||||||
if ((pwr = ephash_lookup_proxy_writer_guid (rd->e.gv->guid_hash, pwr_guid)) != NULL)
|
if ((pwr = entidx_lookup_proxy_writer_guid (rd->e.gv->entity_index, pwr_guid)) != NULL)
|
||||||
{
|
{
|
||||||
struct pwr_rd_match *m;
|
struct pwr_rd_match *m;
|
||||||
|
|
||||||
|
@ -1841,10 +1850,9 @@ static void proxy_writer_drop_connection (const struct ddsi_guid *pwr_guid, stru
|
||||||
ddsrt_mutex_unlock (&pwr->e.lock);
|
ddsrt_mutex_unlock (&pwr->e.lock);
|
||||||
if (m)
|
if (m)
|
||||||
{
|
{
|
||||||
update_reader_init_acknack_count (&rd->e.gv->logconfig, rd->e.gv->guid_hash, &rd->e.guid, m->count);
|
update_reader_init_acknack_count (&rd->e.gv->logconfig, rd->e.gv->entity_index, &rd->e.guid, m->count);
|
||||||
if (m->filtered)
|
if (m->filtered)
|
||||||
nn_defrag_prune(pwr->defrag, &m->rd_guid.prefix, m->last_seq);
|
nn_defrag_prune(pwr->defrag, &m->rd_guid.prefix, m->last_seq);
|
||||||
|
|
||||||
}
|
}
|
||||||
free_pwr_rd_match (m);
|
free_pwr_rd_match (m);
|
||||||
}
|
}
|
||||||
|
@ -1853,7 +1861,7 @@ static void proxy_writer_drop_connection (const struct ddsi_guid *pwr_guid, stru
|
||||||
static void proxy_reader_drop_connection (const struct ddsi_guid *prd_guid, struct writer *wr)
|
static void proxy_reader_drop_connection (const struct ddsi_guid *prd_guid, struct writer *wr)
|
||||||
{
|
{
|
||||||
struct proxy_reader *prd;
|
struct proxy_reader *prd;
|
||||||
if ((prd = ephash_lookup_proxy_reader_guid (wr->e.gv->guid_hash, prd_guid)) != NULL)
|
if ((prd = entidx_lookup_proxy_reader_guid (wr->e.gv->entity_index, prd_guid)) != NULL)
|
||||||
{
|
{
|
||||||
struct prd_wr_match *m;
|
struct prd_wr_match *m;
|
||||||
ddsrt_mutex_lock (&prd->e.lock);
|
ddsrt_mutex_lock (&prd->e.lock);
|
||||||
|
@ -2000,7 +2008,7 @@ static void writer_add_local_connection (struct writer *wr, struct reader *rd)
|
||||||
struct ddsi_serdata *payload = sample.serdata;
|
struct ddsi_serdata *payload = sample.serdata;
|
||||||
/* FIXME: whc has tk reference in its index nodes, which is what we really should be iterating over anyway, and so we don't really have to look them up anymore */
|
/* FIXME: whc has tk reference in its index nodes, which is what we really should be iterating over anyway, and so we don't really have to look them up anymore */
|
||||||
struct ddsi_tkmap_instance *tk = ddsi_tkmap_lookup_instance_ref (tkmap, payload);
|
struct ddsi_tkmap_instance *tk = ddsi_tkmap_lookup_instance_ref (tkmap, payload);
|
||||||
ddsi_make_writer_info (&wrinfo, &wr->e, wr->xqos);
|
ddsi_make_writer_info (&wrinfo, &wr->e, wr->xqos, sample.serdata->statusinfo);
|
||||||
(void) ddsi_rhc_store (rd->rhc, &wrinfo, payload, tk);
|
(void) ddsi_rhc_store (rd->rhc, &wrinfo, payload, tk);
|
||||||
ddsi_tkmap_instance_unref (tkmap, tk);
|
ddsi_tkmap_instance_unref (tkmap, tk);
|
||||||
}
|
}
|
||||||
|
@ -2539,7 +2547,8 @@ static void connect_writer_with_proxy_reader_wrapper (struct entity_common *vwr,
|
||||||
struct proxy_reader *prd = (struct proxy_reader *) vprd;
|
struct proxy_reader *prd = (struct proxy_reader *) vprd;
|
||||||
assert (wr->e.kind == EK_WRITER);
|
assert (wr->e.kind == EK_WRITER);
|
||||||
assert (prd->e.kind == EK_PROXY_READER);
|
assert (prd->e.kind == EK_PROXY_READER);
|
||||||
connect_writer_with_proxy_reader(wr, prd, tnow);
|
assert (is_builtin_endpoint (wr->e.guid.entityid, NN_VENDORID_ECLIPSE) == is_builtin_endpoint (prd->e.guid.entityid, prd->c.vendor));
|
||||||
|
connect_writer_with_proxy_reader (wr, prd, tnow);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void connect_proxy_writer_with_reader_wrapper (struct entity_common *vpwr, struct entity_common *vrd, nn_mtime_t tnow)
|
static void connect_proxy_writer_with_reader_wrapper (struct entity_common *vpwr, struct entity_common *vrd, nn_mtime_t tnow)
|
||||||
|
@ -2548,7 +2557,8 @@ static void connect_proxy_writer_with_reader_wrapper (struct entity_common *vpwr
|
||||||
struct reader *rd = (struct reader *) vrd;
|
struct reader *rd = (struct reader *) vrd;
|
||||||
assert (pwr->e.kind == EK_PROXY_WRITER);
|
assert (pwr->e.kind == EK_PROXY_WRITER);
|
||||||
assert (rd->e.kind == EK_READER);
|
assert (rd->e.kind == EK_READER);
|
||||||
connect_proxy_writer_with_reader(pwr, rd, tnow);
|
assert (is_builtin_endpoint (rd->e.guid.entityid, NN_VENDORID_ECLIPSE) == is_builtin_endpoint (pwr->e.guid.entityid, pwr->c.vendor));
|
||||||
|
connect_proxy_writer_with_reader (pwr, rd, tnow);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void connect_writer_with_reader_wrapper (struct entity_common *vwr, struct entity_common *vrd, nn_mtime_t tnow)
|
static void connect_writer_with_reader_wrapper (struct entity_common *vwr, struct entity_common *vrd, nn_mtime_t tnow)
|
||||||
|
@ -2557,17 +2567,19 @@ static void connect_writer_with_reader_wrapper (struct entity_common *vwr, struc
|
||||||
struct reader *rd = (struct reader *) vrd;
|
struct reader *rd = (struct reader *) vrd;
|
||||||
assert (wr->e.kind == EK_WRITER);
|
assert (wr->e.kind == EK_WRITER);
|
||||||
assert (rd->e.kind == EK_READER);
|
assert (rd->e.kind == EK_READER);
|
||||||
connect_writer_with_reader(wr, rd, tnow);
|
assert (!is_builtin_endpoint (wr->e.guid.entityid, NN_VENDORID_ECLIPSE) || is_local_orphan_endpoint (&wr->e));
|
||||||
|
assert (!is_builtin_endpoint (rd->e.guid.entityid, NN_VENDORID_ECLIPSE));
|
||||||
|
connect_writer_with_reader (wr, rd, tnow);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum entity_kind generic_do_match_mkind (enum entity_kind kind)
|
static enum entity_kind generic_do_match_mkind (enum entity_kind kind, bool local)
|
||||||
{
|
{
|
||||||
switch (kind)
|
switch (kind)
|
||||||
{
|
{
|
||||||
case EK_WRITER: return EK_PROXY_READER;
|
case EK_WRITER: return local ? EK_READER : EK_PROXY_READER;
|
||||||
case EK_READER: return EK_PROXY_WRITER;
|
case EK_READER: return local ? EK_WRITER : EK_PROXY_WRITER;
|
||||||
case EK_PROXY_WRITER: return EK_READER;
|
case EK_PROXY_WRITER: assert (!local); return EK_READER;
|
||||||
case EK_PROXY_READER: return EK_WRITER;
|
case EK_PROXY_READER: assert (!local); return EK_WRITER;
|
||||||
case EK_PARTICIPANT:
|
case EK_PARTICIPANT:
|
||||||
case EK_PROXY_PARTICIPANT:
|
case EK_PROXY_PARTICIPANT:
|
||||||
assert(0);
|
assert(0);
|
||||||
|
@ -2577,88 +2589,29 @@ static enum entity_kind generic_do_match_mkind (enum entity_kind kind)
|
||||||
return EK_WRITER;
|
return EK_WRITER;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum entity_kind generic_do_local_match_mkind (enum entity_kind kind)
|
static void generic_do_match_connect (struct entity_common *e, struct entity_common *em, nn_mtime_t tnow, bool local)
|
||||||
{
|
|
||||||
switch (kind)
|
|
||||||
{
|
|
||||||
case EK_WRITER: return EK_READER;
|
|
||||||
case EK_READER: return EK_WRITER;
|
|
||||||
case EK_PROXY_WRITER:
|
|
||||||
case EK_PROXY_READER:
|
|
||||||
case EK_PARTICIPANT:
|
|
||||||
case EK_PROXY_PARTICIPANT:
|
|
||||||
assert(0);
|
|
||||||
return EK_WRITER;
|
|
||||||
}
|
|
||||||
assert(0);
|
|
||||||
return EK_WRITER;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *generic_do_match_kindstr_us (enum entity_kind kind)
|
|
||||||
{
|
|
||||||
switch (kind)
|
|
||||||
{
|
|
||||||
case EK_WRITER: return "writer";
|
|
||||||
case EK_READER: return "reader";
|
|
||||||
case EK_PROXY_WRITER: return "proxy_writer";
|
|
||||||
case EK_PROXY_READER: return "proxy_reader";
|
|
||||||
case EK_PARTICIPANT: return "participant";
|
|
||||||
case EK_PROXY_PARTICIPANT: return "proxy_participant";
|
|
||||||
}
|
|
||||||
assert(0);
|
|
||||||
return "?";
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *generic_do_match_kindstr (enum entity_kind kind)
|
|
||||||
{
|
|
||||||
switch (kind)
|
|
||||||
{
|
|
||||||
case EK_WRITER: return "writer";
|
|
||||||
case EK_READER: return "reader";
|
|
||||||
case EK_PROXY_WRITER: return "proxy writer";
|
|
||||||
case EK_PROXY_READER: return "proxy reader";
|
|
||||||
case EK_PARTICIPANT: return "participant";
|
|
||||||
case EK_PROXY_PARTICIPANT: return "proxy participant";
|
|
||||||
}
|
|
||||||
assert(0);
|
|
||||||
return "?";
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *generic_do_match_kindabbrev (enum entity_kind kind)
|
|
||||||
{
|
|
||||||
switch (kind)
|
|
||||||
{
|
|
||||||
case EK_WRITER: return "wr";
|
|
||||||
case EK_READER: return "rd";
|
|
||||||
case EK_PROXY_WRITER: return "pwr";
|
|
||||||
case EK_PROXY_READER: return "prd";
|
|
||||||
case EK_PARTICIPANT: return "pp";
|
|
||||||
case EK_PROXY_PARTICIPANT: return "proxypp";
|
|
||||||
}
|
|
||||||
assert(0);
|
|
||||||
return "?";
|
|
||||||
}
|
|
||||||
|
|
||||||
static int generic_do_match_isproxy (const struct entity_common *e)
|
|
||||||
{
|
|
||||||
return e->kind == EK_PROXY_WRITER || e->kind == EK_PROXY_READER || e->kind == EK_PROXY_PARTICIPANT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void generic_do_match_connect (struct entity_common *e, struct entity_common *em, nn_mtime_t tnow)
|
|
||||||
{
|
{
|
||||||
switch (e->kind)
|
switch (e->kind)
|
||||||
{
|
{
|
||||||
case EK_WRITER:
|
case EK_WRITER:
|
||||||
connect_writer_with_proxy_reader_wrapper(e, em, tnow);
|
if (local)
|
||||||
|
connect_writer_with_reader_wrapper (e, em, tnow);
|
||||||
|
else
|
||||||
|
connect_writer_with_proxy_reader_wrapper (e, em, tnow);
|
||||||
break;
|
break;
|
||||||
case EK_READER:
|
case EK_READER:
|
||||||
connect_proxy_writer_with_reader_wrapper(em, e, tnow);
|
if (local)
|
||||||
|
connect_writer_with_reader_wrapper (em, e, tnow);
|
||||||
|
else
|
||||||
|
connect_proxy_writer_with_reader_wrapper (em, e, tnow);
|
||||||
break;
|
break;
|
||||||
case EK_PROXY_WRITER:
|
case EK_PROXY_WRITER:
|
||||||
connect_proxy_writer_with_reader_wrapper(e, em, tnow);
|
assert (!local);
|
||||||
|
connect_proxy_writer_with_reader_wrapper (e, em, tnow);
|
||||||
break;
|
break;
|
||||||
case EK_PROXY_READER:
|
case EK_PROXY_READER:
|
||||||
connect_writer_with_proxy_reader_wrapper(em, e, tnow);
|
assert (!local);
|
||||||
|
connect_writer_with_proxy_reader_wrapper (em, e, tnow);
|
||||||
break;
|
break;
|
||||||
case EK_PARTICIPANT:
|
case EK_PARTICIPANT:
|
||||||
case EK_PROXY_PARTICIPANT:
|
case EK_PROXY_PARTICIPANT:
|
||||||
|
@ -2666,125 +2619,118 @@ static void generic_do_match_connect (struct entity_common *e, struct entity_com
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void generic_do_local_match_connect (struct entity_common *e, struct entity_common *em, nn_mtime_t tnow)
|
static const char *entity_topic_name (const struct entity_common *e)
|
||||||
{
|
{
|
||||||
switch (e->kind)
|
switch (e->kind)
|
||||||
{
|
{
|
||||||
case EK_WRITER:
|
case EK_WRITER:
|
||||||
connect_writer_with_reader_wrapper(e, em, tnow);
|
return ((const struct writer *) e)->xqos->topic_name;
|
||||||
break;
|
|
||||||
case EK_READER:
|
case EK_READER:
|
||||||
connect_writer_with_reader_wrapper(em, e, tnow);
|
return ((const struct reader *) e)->xqos->topic_name;
|
||||||
break;
|
|
||||||
case EK_PROXY_WRITER:
|
case EK_PROXY_WRITER:
|
||||||
case EK_PROXY_READER:
|
case EK_PROXY_READER:
|
||||||
|
return ((const struct generic_proxy_endpoint *) e)->c.xqos->topic_name;
|
||||||
case EK_PARTICIPANT:
|
case EK_PARTICIPANT:
|
||||||
case EK_PROXY_PARTICIPANT:
|
case EK_PROXY_PARTICIPANT:
|
||||||
assert(0);
|
assert (0);
|
||||||
}
|
}
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void generic_do_match (struct entity_common *e, nn_mtime_t tnow)
|
static void generic_do_match (struct entity_common *e, nn_mtime_t tnow, bool local)
|
||||||
{
|
{
|
||||||
struct ephash * const guid_hash = e->gv->guid_hash;
|
static const struct { const char *full; const char *full_us; const char *abbrev; } kindstr[] = {
|
||||||
struct ephash_enum est;
|
[EK_WRITER] = { "writer", "writer", "wr" },
|
||||||
|
[EK_READER] = { "reader", "reader", "rd" },
|
||||||
|
[EK_PROXY_WRITER] = { "proxy writer", "proxy_writer", "pwr" },
|
||||||
|
[EK_PROXY_READER] = { "proxy reader", "proxy_reader", "prd" },
|
||||||
|
[EK_PARTICIPANT] = { "participant", "participant", "pp" },
|
||||||
|
[EK_PROXY_PARTICIPANT] = { "proxy participant", "proxy_participant", "proxypp" }
|
||||||
|
};
|
||||||
|
|
||||||
|
enum entity_kind mkind = generic_do_match_mkind (e->kind, local);
|
||||||
|
struct entity_index const * const entidx = e->gv->entity_index;
|
||||||
|
struct entidx_enum it;
|
||||||
struct entity_common *em;
|
struct entity_common *em;
|
||||||
enum entity_kind mkind = generic_do_match_mkind(e->kind);
|
|
||||||
if (!is_builtin_entityid (e->guid.entityid, NN_VENDORID_ECLIPSE))
|
if (!is_builtin_entityid (e->guid.entityid, NN_VENDORID_ECLIPSE) || (local && is_local_orphan_endpoint (e)))
|
||||||
{
|
{
|
||||||
EELOGDISC (e, "match_%s_with_%ss(%s "PGUIDFMT") scanning all %ss\n",
|
/* Non-builtins need matching on topics, the local orphan endpoints
|
||||||
generic_do_match_kindstr_us (e->kind), generic_do_match_kindstr_us (mkind),
|
are a bit weird because they reuse the builtin entityids but
|
||||||
generic_do_match_kindabbrev (e->kind), PGUID (e->guid),
|
otherwise need to be treated as normal readers */
|
||||||
generic_do_match_kindstr(mkind));
|
struct match_entities_range_key max;
|
||||||
|
const char *tp = entity_topic_name (e);
|
||||||
|
EELOGDISC (e, "match_%s_with_%ss(%s "PGUIDFMT") scanning all %ss%s%s\n",
|
||||||
|
kindstr[e->kind].full_us, kindstr[mkind].full_us,
|
||||||
|
kindstr[e->kind].abbrev, PGUID (e->guid),
|
||||||
|
kindstr[mkind].abbrev,
|
||||||
|
tp ? " of topic " : "", tp ? tp : "");
|
||||||
/* Note: we visit at least all proxies that existed when we called
|
/* Note: we visit at least all proxies that existed when we called
|
||||||
init (with the -- possible -- exception of ones that were
|
init (with the -- possible -- exception of ones that were
|
||||||
deleted between our calling init and our reaching it while
|
deleted between our calling init and our reaching it while
|
||||||
enumerating), but we may visit a single proxy reader multiple
|
enumerating), but we may visit a single proxy reader multiple
|
||||||
times. */
|
times. */
|
||||||
ephash_enum_init (&est, guid_hash, mkind);
|
entidx_enum_init_topic (&it, entidx, mkind, tp, &max);
|
||||||
while ((em = ephash_enum_next (&est)) != NULL)
|
while ((em = entidx_enum_next_max (&it, &max)) != NULL)
|
||||||
generic_do_match_connect(e, em, tnow);
|
generic_do_match_connect (e, em, tnow, local);
|
||||||
ephash_enum_fini (&est);
|
entidx_enum_fini (&it);
|
||||||
}
|
}
|
||||||
else
|
else if (!local)
|
||||||
{
|
{
|
||||||
/* Built-ins have fixed QoS */
|
/* Built-ins have fixed QoS and a known entity id to use, so instead of
|
||||||
ddsi_entityid_t tgt_ent = builtin_entityid_match (e->guid.entityid);
|
looking for the right topic, just probe the matching GUIDs for all
|
||||||
enum entity_kind pkind = generic_do_match_isproxy (e) ? EK_PARTICIPANT : EK_PROXY_PARTICIPANT;
|
(proxy) participants. Local matching never needs to look at the
|
||||||
|
discovery endpoints */
|
||||||
|
const ddsi_entityid_t tgt_ent = builtin_entityid_match (e->guid.entityid);
|
||||||
|
const bool isproxy = (e->kind == EK_PROXY_WRITER || e->kind == EK_PROXY_READER || e->kind == EK_PROXY_PARTICIPANT);
|
||||||
|
enum entity_kind pkind = isproxy ? EK_PARTICIPANT : EK_PROXY_PARTICIPANT;
|
||||||
EELOGDISC (e, "match_%s_with_%ss(%s "PGUIDFMT") scanning %sparticipants tgt=%"PRIx32"\n",
|
EELOGDISC (e, "match_%s_with_%ss(%s "PGUIDFMT") scanning %sparticipants tgt=%"PRIx32"\n",
|
||||||
generic_do_match_kindstr_us (e->kind), generic_do_match_kindstr_us (mkind),
|
kindstr[e->kind].full_us, kindstr[mkind].full_us,
|
||||||
generic_do_match_kindabbrev (e->kind), PGUID (e->guid),
|
kindstr[e->kind].abbrev, PGUID (e->guid),
|
||||||
generic_do_match_isproxy (e) ? "" : "proxy ",
|
isproxy ? "" : "proxy ", tgt_ent.u);
|
||||||
tgt_ent.u);
|
|
||||||
if (tgt_ent.u != NN_ENTITYID_UNKNOWN)
|
if (tgt_ent.u != NN_ENTITYID_UNKNOWN)
|
||||||
{
|
{
|
||||||
struct entity_common *ep;
|
entidx_enum_init (&it, entidx, pkind);
|
||||||
ephash_enum_init (&est, guid_hash, pkind);
|
while ((em = entidx_enum_next (&it)) != NULL)
|
||||||
while ((ep = ephash_enum_next (&est)) != NULL)
|
|
||||||
{
|
{
|
||||||
ddsi_guid_t tgt_guid;
|
const ddsi_guid_t tgt_guid = { em->guid.prefix, tgt_ent };
|
||||||
tgt_guid.prefix = ep->guid.prefix;
|
struct entity_common *ep;
|
||||||
tgt_guid.entityid = tgt_ent;
|
if ((ep = entidx_lookup_guid (entidx, &tgt_guid, mkind)) != NULL)
|
||||||
if ((em = ephash_lookup_guid (guid_hash, &tgt_guid, mkind)) != NULL)
|
generic_do_match_connect (e, ep, tnow, local);
|
||||||
generic_do_match_connect(e, em, tnow);
|
|
||||||
}
|
}
|
||||||
ephash_enum_fini (&est);
|
entidx_enum_fini (&it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void generic_do_local_match (struct entity_common *e, nn_mtime_t tnow)
|
|
||||||
{
|
|
||||||
struct ephash_enum est;
|
|
||||||
struct entity_common *em;
|
|
||||||
enum entity_kind mkind;
|
|
||||||
if (is_builtin_entityid (e->guid.entityid, NN_VENDORID_ECLIPSE) && !is_local_orphan_endpoint (e))
|
|
||||||
/* never a need for local matches on discovery endpoints */
|
|
||||||
return;
|
|
||||||
mkind = generic_do_local_match_mkind (e->kind);
|
|
||||||
EELOGDISC (e, "match_%s_with_%ss(%s "PGUIDFMT") scanning all %ss\n",
|
|
||||||
generic_do_match_kindstr_us (e->kind), generic_do_match_kindstr_us (mkind),
|
|
||||||
generic_do_match_kindabbrev (e->kind), PGUID (e->guid),
|
|
||||||
generic_do_match_kindstr(mkind));
|
|
||||||
/* Note: we visit at least all proxies that existed when we called
|
|
||||||
init (with the -- possible -- exception of ones that were
|
|
||||||
deleted between our calling init and our reaching it while
|
|
||||||
enumerating), but we may visit a single proxy reader multiple
|
|
||||||
times. */
|
|
||||||
ephash_enum_init (&est, e->gv->guid_hash, mkind);
|
|
||||||
while ((em = ephash_enum_next (&est)) != NULL)
|
|
||||||
generic_do_local_match_connect (e, em, tnow);
|
|
||||||
ephash_enum_fini (&est);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void match_writer_with_proxy_readers (struct writer *wr, nn_mtime_t tnow)
|
static void match_writer_with_proxy_readers (struct writer *wr, nn_mtime_t tnow)
|
||||||
{
|
{
|
||||||
generic_do_match (&wr->e, tnow);
|
generic_do_match (&wr->e, tnow, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void match_writer_with_local_readers (struct writer *wr, nn_mtime_t tnow)
|
static void match_writer_with_local_readers (struct writer *wr, nn_mtime_t tnow)
|
||||||
{
|
{
|
||||||
generic_do_local_match (&wr->e, tnow);
|
generic_do_match (&wr->e, tnow, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void match_reader_with_proxy_writers (struct reader *rd, nn_mtime_t tnow)
|
static void match_reader_with_proxy_writers (struct reader *rd, nn_mtime_t tnow)
|
||||||
{
|
{
|
||||||
generic_do_match (&rd->e, tnow);
|
generic_do_match (&rd->e, tnow, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void match_reader_with_local_writers (struct reader *rd, nn_mtime_t tnow)
|
static void match_reader_with_local_writers (struct reader *rd, nn_mtime_t tnow)
|
||||||
{
|
{
|
||||||
generic_do_local_match (&rd->e, tnow);
|
generic_do_match (&rd->e, tnow, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void match_proxy_writer_with_readers (struct proxy_writer *pwr, nn_mtime_t tnow)
|
static void match_proxy_writer_with_readers (struct proxy_writer *pwr, nn_mtime_t tnow)
|
||||||
{
|
{
|
||||||
generic_do_match (&pwr->e, tnow);
|
generic_do_match (&pwr->e, tnow, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void match_proxy_reader_with_writers (struct proxy_reader *prd, nn_mtime_t tnow)
|
static void match_proxy_reader_with_writers (struct proxy_reader *prd, nn_mtime_t tnow)
|
||||||
{
|
{
|
||||||
generic_do_match(&prd->e, tnow);
|
generic_do_match(&prd->e, tnow, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ENDPOINT --------------------------------------------------------- */
|
/* ENDPOINT --------------------------------------------------------- */
|
||||||
|
@ -3219,7 +3165,7 @@ static dds_return_t new_writer_guid (struct writer **wr_out, const struct ddsi_g
|
||||||
nn_mtime_t tnow = now_mt ();
|
nn_mtime_t tnow = now_mt ();
|
||||||
|
|
||||||
assert (is_writer_entityid (guid->entityid));
|
assert (is_writer_entityid (guid->entityid));
|
||||||
assert (ephash_lookup_writer_guid (pp->e.gv->guid_hash, guid) == NULL);
|
assert (entidx_lookup_writer_guid (pp->e.gv->entity_index, guid) == NULL);
|
||||||
assert (memcmp (&guid->prefix, &pp->e.guid.prefix, sizeof (guid->prefix)) == 0);
|
assert (memcmp (&guid->prefix, &pp->e.guid.prefix, sizeof (guid->prefix)) == 0);
|
||||||
|
|
||||||
new_reader_writer_common (&pp->e.gv->logconfig, guid, topic, xqos);
|
new_reader_writer_common (&pp->e.gv->logconfig, guid, topic, xqos);
|
||||||
|
@ -3235,13 +3181,13 @@ static dds_return_t new_writer_guid (struct writer **wr_out, const struct ddsi_g
|
||||||
endpoint_common_init (&wr->e, &wr->c, pp->e.gv, EK_WRITER, guid, group_guid, pp, onlylocal);
|
endpoint_common_init (&wr->e, &wr->c, pp->e.gv, EK_WRITER, guid, group_guid, pp, onlylocal);
|
||||||
new_writer_guid_common_init(wr, topic, xqos, whc, status_cb, status_entity);
|
new_writer_guid_common_init(wr, topic, xqos, whc, status_cb, status_entity);
|
||||||
|
|
||||||
/* guid_hash needed for protocol handling, so add it before we send
|
/* entity_index needed for protocol handling, so add it before we send
|
||||||
out our first message. Also: needed for matching, and swapping
|
out our first message. Also: needed for matching, and swapping
|
||||||
the order if hash insert & matching creates a window during which
|
the order if hash insert & matching creates a window during which
|
||||||
neither of two endpoints being created in parallel can discover
|
neither of two endpoints being created in parallel can discover
|
||||||
the other. */
|
the other. */
|
||||||
ddsrt_mutex_lock (&wr->e.lock);
|
ddsrt_mutex_lock (&wr->e.lock);
|
||||||
ephash_insert_writer_guid (pp->e.gv->guid_hash, wr);
|
entidx_insert_writer_guid (pp->e.gv->entity_index, wr);
|
||||||
builtintopic_write (wr->e.gv->builtin_topic_interface, &wr->e, now(), true);
|
builtintopic_write (wr->e.gv->builtin_topic_interface, &wr->e, now(), true);
|
||||||
ddsrt_mutex_unlock (&wr->e.lock);
|
ddsrt_mutex_unlock (&wr->e.lock);
|
||||||
|
|
||||||
|
@ -3279,14 +3225,14 @@ dds_return_t new_writer (struct writer **wr_out, struct q_globals *gv, struct dd
|
||||||
dds_return_t rc;
|
dds_return_t rc;
|
||||||
uint32_t kind;
|
uint32_t kind;
|
||||||
|
|
||||||
if ((pp = ephash_lookup_participant_guid (gv->guid_hash, ppguid)) == NULL)
|
if ((pp = entidx_lookup_participant_guid (gv->entity_index, ppguid)) == NULL)
|
||||||
{
|
{
|
||||||
GVLOGDISC ("new_writer - participant "PGUIDFMT" not found\n", PGUID (*ppguid));
|
GVLOGDISC ("new_writer - participant "PGUIDFMT" not found\n", PGUID (*ppguid));
|
||||||
return DDS_RETCODE_BAD_PARAMETER;
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* participant can't be freed while we're mucking around cos we are
|
/* participant can't be freed while we're mucking around cos we are
|
||||||
awake and do not touch the thread's vtime (ephash_lookup already
|
awake and do not touch the thread's vtime (entidx_lookup already
|
||||||
verifies we're awake) */
|
verifies we're awake) */
|
||||||
wrguid->prefix = pp->e.guid.prefix;
|
wrguid->prefix = pp->e.guid.prefix;
|
||||||
kind = topic->topickind_no_key ? NN_ENTITYID_KIND_WRITER_NO_KEY : NN_ENTITYID_KIND_WRITER_WITH_KEY;
|
kind = topic->topickind_no_key ? NN_ENTITYID_KIND_WRITER_NO_KEY : NN_ENTITYID_KIND_WRITER_WITH_KEY;
|
||||||
|
@ -3312,7 +3258,7 @@ struct local_orphan_writer *new_local_orphan_writer (struct q_globals *gv, ddsi_
|
||||||
wr->c.pp = NULL;
|
wr->c.pp = NULL;
|
||||||
memset (&wr->c.group_guid, 0, sizeof (wr->c.group_guid));
|
memset (&wr->c.group_guid, 0, sizeof (wr->c.group_guid));
|
||||||
new_writer_guid_common_init (wr, topic, xqos, whc, 0, NULL);
|
new_writer_guid_common_init (wr, topic, xqos, whc, 0, NULL);
|
||||||
ephash_insert_writer_guid (gv->guid_hash, wr);
|
entidx_insert_writer_guid (gv->entity_index, wr);
|
||||||
builtintopic_write (gv->builtin_topic_interface, &wr->e, now(), true);
|
builtintopic_write (gv->builtin_topic_interface, &wr->e, now(), true);
|
||||||
match_writer_with_local_readers (wr, tnow);
|
match_writer_with_local_readers (wr, tnow);
|
||||||
return lowr;
|
return lowr;
|
||||||
|
@ -3343,7 +3289,7 @@ static void gc_delete_writer (struct gcreq *gcreq)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tear down connections -- no proxy reader can be adding/removing
|
/* Tear down connections -- no proxy reader can be adding/removing
|
||||||
us now, because we can't be found via guid_hash anymore. We
|
us now, because we can't be found via entity_index anymore. We
|
||||||
therefore need not take lock. */
|
therefore need not take lock. */
|
||||||
|
|
||||||
while (!ddsrt_avl_is_empty (&wr->readers))
|
while (!ddsrt_avl_is_empty (&wr->readers))
|
||||||
|
@ -3425,7 +3371,7 @@ dds_return_t unblock_throttled_writer (struct q_globals *gv, const struct ddsi_g
|
||||||
{
|
{
|
||||||
struct writer *wr;
|
struct writer *wr;
|
||||||
assert (is_writer_entityid (guid->entityid));
|
assert (is_writer_entityid (guid->entityid));
|
||||||
if ((wr = ephash_lookup_writer_guid (gv->guid_hash, guid)) == NULL)
|
if ((wr = entidx_lookup_writer_guid (gv->entity_index, guid)) == NULL)
|
||||||
{
|
{
|
||||||
GVLOGDISC ("unblock_throttled_writer(guid "PGUIDFMT") - unknown guid\n", PGUID (*guid));
|
GVLOGDISC ("unblock_throttled_writer(guid "PGUIDFMT") - unknown guid\n", PGUID (*guid));
|
||||||
return DDS_RETCODE_BAD_PARAMETER;
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
|
@ -3443,7 +3389,7 @@ dds_return_t delete_writer_nolinger_locked (struct writer *wr)
|
||||||
ASSERT_MUTEX_HELD (&wr->e.lock);
|
ASSERT_MUTEX_HELD (&wr->e.lock);
|
||||||
builtintopic_write (wr->e.gv->builtin_topic_interface, &wr->e, now(), false);
|
builtintopic_write (wr->e.gv->builtin_topic_interface, &wr->e, now(), false);
|
||||||
local_reader_ary_setinvalid (&wr->rdary);
|
local_reader_ary_setinvalid (&wr->rdary);
|
||||||
ephash_remove_writer_guid (wr->e.gv->guid_hash, wr);
|
entidx_remove_writer_guid (wr->e.gv->entity_index, wr);
|
||||||
writer_set_state (wr, WRST_DELETING);
|
writer_set_state (wr, WRST_DELETING);
|
||||||
if (wr->lease_duration != NULL) {
|
if (wr->lease_duration != NULL) {
|
||||||
ddsrt_mutex_lock (&wr->c.pp->e.lock);
|
ddsrt_mutex_lock (&wr->c.pp->e.lock);
|
||||||
|
@ -3466,7 +3412,7 @@ dds_return_t delete_writer_nolinger (struct q_globals *gv, const struct ddsi_gui
|
||||||
DDSI participants. But it would be somewhat more elegant to do it
|
DDSI participants. But it would be somewhat more elegant to do it
|
||||||
differently. */
|
differently. */
|
||||||
assert (is_writer_entityid (guid->entityid));
|
assert (is_writer_entityid (guid->entityid));
|
||||||
if ((wr = ephash_lookup_writer_guid (gv->guid_hash, guid)) == NULL)
|
if ((wr = entidx_lookup_writer_guid (gv->entity_index, guid)) == NULL)
|
||||||
{
|
{
|
||||||
GVLOGDISC ("delete_writer_nolinger(guid "PGUIDFMT") - unknown guid\n", PGUID (*guid));
|
GVLOGDISC ("delete_writer_nolinger(guid "PGUIDFMT") - unknown guid\n", PGUID (*guid));
|
||||||
return DDS_RETCODE_BAD_PARAMETER;
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
|
@ -3490,7 +3436,7 @@ dds_return_t delete_writer (struct q_globals *gv, const struct ddsi_guid *guid)
|
||||||
{
|
{
|
||||||
struct writer *wr;
|
struct writer *wr;
|
||||||
struct whc_state whcst;
|
struct whc_state whcst;
|
||||||
if ((wr = ephash_lookup_writer_guid (gv->guid_hash, guid)) == NULL)
|
if ((wr = entidx_lookup_writer_guid (gv->entity_index, guid)) == NULL)
|
||||||
{
|
{
|
||||||
GVLOGDISC ("delete_writer(guid "PGUIDFMT") - unknown guid\n", PGUID (*guid));
|
GVLOGDISC ("delete_writer(guid "PGUIDFMT") - unknown guid\n", PGUID (*guid));
|
||||||
return DDS_RETCODE_BAD_PARAMETER;
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
|
@ -3650,7 +3596,7 @@ static dds_return_t new_reader_guid
|
||||||
nn_mtime_t tnow = now_mt ();
|
nn_mtime_t tnow = now_mt ();
|
||||||
|
|
||||||
assert (!is_writer_entityid (guid->entityid));
|
assert (!is_writer_entityid (guid->entityid));
|
||||||
assert (ephash_lookup_reader_guid (pp->e.gv->guid_hash, guid) == NULL);
|
assert (entidx_lookup_reader_guid (pp->e.gv->entity_index, guid) == NULL);
|
||||||
assert (memcmp (&guid->prefix, &pp->e.guid.prefix, sizeof (guid->prefix)) == 0);
|
assert (memcmp (&guid->prefix, &pp->e.guid.prefix, sizeof (guid->prefix)) == 0);
|
||||||
|
|
||||||
new_reader_writer_common (&pp->e.gv->logconfig, guid, topic, xqos);
|
new_reader_writer_common (&pp->e.gv->logconfig, guid, topic, xqos);
|
||||||
|
@ -3765,7 +3711,7 @@ static dds_return_t new_reader_guid
|
||||||
ddsrt_avl_init (&rd_local_writers_treedef, &rd->local_writers);
|
ddsrt_avl_init (&rd_local_writers_treedef, &rd->local_writers);
|
||||||
|
|
||||||
ddsrt_mutex_lock (&rd->e.lock);
|
ddsrt_mutex_lock (&rd->e.lock);
|
||||||
ephash_insert_reader_guid (pp->e.gv->guid_hash, rd);
|
entidx_insert_reader_guid (pp->e.gv->entity_index, rd);
|
||||||
builtintopic_write (pp->e.gv->builtin_topic_interface, &rd->e, now(), true);
|
builtintopic_write (pp->e.gv->builtin_topic_interface, &rd->e, now(), true);
|
||||||
ddsrt_mutex_unlock (&rd->e.lock);
|
ddsrt_mutex_unlock (&rd->e.lock);
|
||||||
|
|
||||||
|
@ -3793,7 +3739,7 @@ dds_return_t new_reader
|
||||||
dds_return_t rc;
|
dds_return_t rc;
|
||||||
uint32_t kind;
|
uint32_t kind;
|
||||||
|
|
||||||
if ((pp = ephash_lookup_participant_guid (gv->guid_hash, ppguid)) == NULL)
|
if ((pp = entidx_lookup_participant_guid (gv->entity_index, ppguid)) == NULL)
|
||||||
{
|
{
|
||||||
GVLOGDISC ("new_reader - participant "PGUIDFMT" not found\n", PGUID (*ppguid));
|
GVLOGDISC ("new_reader - participant "PGUIDFMT" not found\n", PGUID (*ppguid));
|
||||||
return DDS_RETCODE_BAD_PARAMETER;
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
|
@ -3861,14 +3807,14 @@ dds_return_t delete_reader (struct q_globals *gv, const struct ddsi_guid *guid)
|
||||||
{
|
{
|
||||||
struct reader *rd;
|
struct reader *rd;
|
||||||
assert (!is_writer_entityid (guid->entityid));
|
assert (!is_writer_entityid (guid->entityid));
|
||||||
if ((rd = ephash_lookup_reader_guid (gv->guid_hash, guid)) == NULL)
|
if ((rd = entidx_lookup_reader_guid (gv->entity_index, guid)) == NULL)
|
||||||
{
|
{
|
||||||
GVLOGDISC ("delete_reader_guid(guid "PGUIDFMT") - unknown guid\n", PGUID (*guid));
|
GVLOGDISC ("delete_reader_guid(guid "PGUIDFMT") - unknown guid\n", PGUID (*guid));
|
||||||
return DDS_RETCODE_BAD_PARAMETER;
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
}
|
}
|
||||||
GVLOGDISC ("delete_reader_guid(guid "PGUIDFMT") ...\n", PGUID (*guid));
|
GVLOGDISC ("delete_reader_guid(guid "PGUIDFMT") ...\n", PGUID (*guid));
|
||||||
builtintopic_write (rd->e.gv->builtin_topic_interface, &rd->e, now(), false);
|
builtintopic_write (rd->e.gv->builtin_topic_interface, &rd->e, now(), false);
|
||||||
ephash_remove_reader_guid (gv->guid_hash, rd);
|
entidx_remove_reader_guid (gv->entity_index, rd);
|
||||||
gcreq_reader (rd);
|
gcreq_reader (rd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -4201,7 +4147,7 @@ void new_proxy_participant
|
||||||
struct proxy_participant *proxypp;
|
struct proxy_participant *proxypp;
|
||||||
|
|
||||||
assert (ppguid->entityid.u == NN_ENTITYID_PARTICIPANT);
|
assert (ppguid->entityid.u == NN_ENTITYID_PARTICIPANT);
|
||||||
assert (ephash_lookup_proxy_participant_guid (gv->guid_hash, ppguid) == NULL);
|
assert (entidx_lookup_proxy_participant_guid (gv->entity_index, ppguid) == NULL);
|
||||||
assert (privileged_pp_guid == NULL || privileged_pp_guid->entityid.u == NN_ENTITYID_PARTICIPANT);
|
assert (privileged_pp_guid == NULL || privileged_pp_guid->entityid.u == NN_ENTITYID_PARTICIPANT);
|
||||||
|
|
||||||
prune_deleted_participant_guids (gv->deleted_participants, now_mt ());
|
prune_deleted_participant_guids (gv->deleted_participants, now_mt ());
|
||||||
|
@ -4236,7 +4182,7 @@ void new_proxy_participant
|
||||||
|
|
||||||
{
|
{
|
||||||
struct proxy_participant *privpp;
|
struct proxy_participant *privpp;
|
||||||
privpp = ephash_lookup_proxy_participant_guid (gv->guid_hash, &proxypp->privileged_pp_guid);
|
privpp = entidx_lookup_proxy_participant_guid (gv->entity_index, &proxypp->privileged_pp_guid);
|
||||||
|
|
||||||
ddsrt_fibheap_init (&lease_fhdef_proxypp, &proxypp->leaseheap_auto);
|
ddsrt_fibheap_init (&lease_fhdef_proxypp, &proxypp->leaseheap_auto);
|
||||||
ddsrt_fibheap_init (&lease_fhdef_proxypp, &proxypp->leaseheap_man);
|
ddsrt_fibheap_init (&lease_fhdef_proxypp, &proxypp->leaseheap_man);
|
||||||
|
@ -4309,7 +4255,7 @@ void new_proxy_participant
|
||||||
|
|
||||||
/* Proxy participant must be in the hash tables for
|
/* Proxy participant must be in the hash tables for
|
||||||
new_proxy_{writer,reader} to work */
|
new_proxy_{writer,reader} to work */
|
||||||
ephash_insert_proxy_participant_guid (gv->guid_hash, proxypp);
|
entidx_insert_proxy_participant_guid (gv->entity_index, proxypp);
|
||||||
|
|
||||||
/* TODO: Do security checks on the proxy participant. Either add the endpoints or delete the proxy. */
|
/* TODO: Do security checks on the proxy participant. Either add the endpoints or delete the proxy. */
|
||||||
add_proxy_builtin_endpoints(gv, ppguid, proxypp, timestamp);
|
add_proxy_builtin_endpoints(gv, ppguid, proxypp, timestamp);
|
||||||
|
@ -4489,12 +4435,12 @@ static void delete_ppt (struct proxy_participant *proxypp, nn_wctime_t timestamp
|
||||||
/* if any proxy participants depend on this participant, delete them */
|
/* if any proxy participants depend on this participant, delete them */
|
||||||
ELOGDISC (proxypp, "delete_ppt("PGUIDFMT") - deleting dependent proxy participants\n", PGUID (proxypp->e.guid));
|
ELOGDISC (proxypp, "delete_ppt("PGUIDFMT") - deleting dependent proxy participants\n", PGUID (proxypp->e.guid));
|
||||||
{
|
{
|
||||||
struct ephash_enum_proxy_participant est;
|
struct entidx_enum_proxy_participant est;
|
||||||
struct proxy_participant *p;
|
struct proxy_participant *p;
|
||||||
ephash_enum_proxy_participant_init (&est, proxypp->e.gv->guid_hash);
|
entidx_enum_proxy_participant_init (&est, proxypp->e.gv->entity_index);
|
||||||
while ((p = ephash_enum_proxy_participant_next (&est)) != NULL)
|
while ((p = entidx_enum_proxy_participant_next (&est)) != NULL)
|
||||||
delete_or_detach_dependent_pp(p, proxypp, timestamp, isimplicit);
|
delete_or_detach_dependent_pp(p, proxypp, timestamp, isimplicit);
|
||||||
ephash_enum_proxy_participant_fini (&est);
|
entidx_enum_proxy_participant_fini (&est);
|
||||||
}
|
}
|
||||||
|
|
||||||
ddsrt_mutex_lock (&proxypp->e.lock);
|
ddsrt_mutex_lock (&proxypp->e.lock);
|
||||||
|
@ -4550,16 +4496,16 @@ void purge_proxy_participants (struct q_globals *gv, const nn_locator_t *loc, bo
|
||||||
/* FIXME: check whether addr:port can't be reused for a new connection by the time we get here. */
|
/* FIXME: check whether addr:port can't be reused for a new connection by the time we get here. */
|
||||||
/* NOTE: This function exists for the sole purpose of cleaning up after closing a TCP connection in ddsi_tcp_close_conn and the state of the calling thread could be anything at this point. Because of that we do the unspeakable and toggle the thread state conditionally. We can't afford to have it in "asleep", as that causes a race with the garbage collector. */
|
/* NOTE: This function exists for the sole purpose of cleaning up after closing a TCP connection in ddsi_tcp_close_conn and the state of the calling thread could be anything at this point. Because of that we do the unspeakable and toggle the thread state conditionally. We can't afford to have it in "asleep", as that causes a race with the garbage collector. */
|
||||||
struct thread_state1 * const ts1 = lookup_thread_state ();
|
struct thread_state1 * const ts1 = lookup_thread_state ();
|
||||||
struct ephash_enum_proxy_participant est;
|
struct entidx_enum_proxy_participant est;
|
||||||
struct proxy_purge_data data;
|
struct proxy_purge_data data;
|
||||||
|
|
||||||
thread_state_awake_fixed_domain (ts1);
|
thread_state_awake_fixed_domain (ts1);
|
||||||
data.loc = loc;
|
data.loc = loc;
|
||||||
data.timestamp = now();
|
data.timestamp = now();
|
||||||
ephash_enum_proxy_participant_init (&est, gv->guid_hash);
|
entidx_enum_proxy_participant_init (&est, gv->entity_index);
|
||||||
while ((data.proxypp = ephash_enum_proxy_participant_next (&est)) != NULL)
|
while ((data.proxypp = entidx_enum_proxy_participant_next (&est)) != NULL)
|
||||||
addrset_forall (data.proxypp->as_meta, purge_helper, &data);
|
addrset_forall (data.proxypp->as_meta, purge_helper, &data);
|
||||||
ephash_enum_proxy_participant_fini (&est);
|
entidx_enum_proxy_participant_fini (&est);
|
||||||
|
|
||||||
/* Shouldn't try to keep pinging clients once they're gone */
|
/* Shouldn't try to keep pinging clients once they're gone */
|
||||||
if (delete_from_as_disc)
|
if (delete_from_as_disc)
|
||||||
|
@ -4574,7 +4520,7 @@ int delete_proxy_participant_by_guid (struct q_globals *gv, const struct ddsi_gu
|
||||||
|
|
||||||
GVLOGDISC ("delete_proxy_participant_by_guid("PGUIDFMT") ", PGUID (*guid));
|
GVLOGDISC ("delete_proxy_participant_by_guid("PGUIDFMT") ", PGUID (*guid));
|
||||||
ddsrt_mutex_lock (&gv->lock);
|
ddsrt_mutex_lock (&gv->lock);
|
||||||
ppt = ephash_lookup_proxy_participant_guid (gv->guid_hash, guid);
|
ppt = entidx_lookup_proxy_participant_guid (gv->entity_index, guid);
|
||||||
if (ppt == NULL)
|
if (ppt == NULL)
|
||||||
{
|
{
|
||||||
ddsrt_mutex_unlock (&gv->lock);
|
ddsrt_mutex_unlock (&gv->lock);
|
||||||
|
@ -4584,7 +4530,7 @@ int delete_proxy_participant_by_guid (struct q_globals *gv, const struct ddsi_gu
|
||||||
GVLOGDISC ("- deleting\n");
|
GVLOGDISC ("- deleting\n");
|
||||||
builtintopic_write (gv->builtin_topic_interface, &ppt->e, timestamp, false);
|
builtintopic_write (gv->builtin_topic_interface, &ppt->e, timestamp, false);
|
||||||
remember_deleted_participant_guid (gv->deleted_participants, &ppt->e.guid);
|
remember_deleted_participant_guid (gv->deleted_participants, &ppt->e.guid);
|
||||||
ephash_remove_proxy_participant_guid (gv->guid_hash, ppt);
|
entidx_remove_proxy_participant_guid (gv->entity_index, ppt);
|
||||||
ddsrt_mutex_unlock (&gv->lock);
|
ddsrt_mutex_unlock (&gv->lock);
|
||||||
delete_ppt (ppt, timestamp, isimplicit);
|
delete_ppt (ppt, timestamp, isimplicit);
|
||||||
|
|
||||||
|
@ -4597,7 +4543,7 @@ uint64_t get_entity_instance_id (const struct q_globals *gv, const struct ddsi_g
|
||||||
struct entity_common *e;
|
struct entity_common *e;
|
||||||
uint64_t iid = 0;
|
uint64_t iid = 0;
|
||||||
thread_state_awake (ts1, gv);
|
thread_state_awake (ts1, gv);
|
||||||
if ((e = ephash_lookup_guid_untyped (gv->guid_hash, guid)) != NULL)
|
if ((e = entidx_lookup_guid_untyped (gv->entity_index, guid)) != NULL)
|
||||||
iid = e->iid;
|
iid = e->iid;
|
||||||
thread_state_asleep (ts1);
|
thread_state_asleep (ts1);
|
||||||
return iid;
|
return iid;
|
||||||
|
@ -4679,9 +4625,9 @@ int new_proxy_writer (struct q_globals *gv, const struct ddsi_guid *ppguid, cons
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
assert (is_writer_entityid (guid->entityid));
|
assert (is_writer_entityid (guid->entityid));
|
||||||
assert (ephash_lookup_proxy_writer_guid (gv->guid_hash, guid) == NULL);
|
assert (entidx_lookup_proxy_writer_guid (gv->entity_index, guid) == NULL);
|
||||||
|
|
||||||
if ((proxypp = ephash_lookup_proxy_participant_guid (gv->guid_hash, ppguid)) == NULL)
|
if ((proxypp = entidx_lookup_proxy_participant_guid (gv->entity_index, ppguid)) == NULL)
|
||||||
{
|
{
|
||||||
GVWARNING ("new_proxy_writer("PGUIDFMT"): proxy participant unknown\n", PGUID (*guid));
|
GVWARNING ("new_proxy_writer("PGUIDFMT"): proxy participant unknown\n", PGUID (*guid));
|
||||||
return DDS_RETCODE_BAD_PARAMETER;
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
|
@ -4781,7 +4727,7 @@ int new_proxy_writer (struct q_globals *gv, const struct ddsi_guid *ppguid, cons
|
||||||
|
|
||||||
/* locking the entity prevents matching while the built-in topic hasn't been published yet */
|
/* locking the entity prevents matching while the built-in topic hasn't been published yet */
|
||||||
ddsrt_mutex_lock (&pwr->e.lock);
|
ddsrt_mutex_lock (&pwr->e.lock);
|
||||||
ephash_insert_proxy_writer_guid (gv->guid_hash, pwr);
|
entidx_insert_proxy_writer_guid (gv->entity_index, pwr);
|
||||||
builtintopic_write (gv->builtin_topic_interface, &pwr->e, timestamp, true);
|
builtintopic_write (gv->builtin_topic_interface, &pwr->e, timestamp, true);
|
||||||
ddsrt_mutex_unlock (&pwr->e.lock);
|
ddsrt_mutex_unlock (&pwr->e.lock);
|
||||||
|
|
||||||
|
@ -4817,7 +4763,7 @@ void update_proxy_writer (struct proxy_writer *pwr, seqno_t seq, struct addrset
|
||||||
m = ddsrt_avl_iter_first (&pwr_readers_treedef, &pwr->readers, &iter);
|
m = ddsrt_avl_iter_first (&pwr_readers_treedef, &pwr->readers, &iter);
|
||||||
while (m)
|
while (m)
|
||||||
{
|
{
|
||||||
rd = ephash_lookup_reader_guid (pwr->e.gv->guid_hash, &m->rd_guid);
|
rd = entidx_lookup_reader_guid (pwr->e.gv->entity_index, &m->rd_guid);
|
||||||
if (rd)
|
if (rd)
|
||||||
{
|
{
|
||||||
qxev_pwr_entityid (pwr, &rd->e.guid);
|
qxev_pwr_entityid (pwr, &rd->e.guid);
|
||||||
|
@ -4871,7 +4817,7 @@ void update_proxy_reader (struct proxy_reader *prd, seqno_t seq, struct addrset
|
||||||
}
|
}
|
||||||
|
|
||||||
ddsrt_mutex_unlock (&prd->e.lock);
|
ddsrt_mutex_unlock (&prd->e.lock);
|
||||||
wr = ephash_lookup_writer_guid (prd->e.gv->guid_hash, &wrguid);
|
wr = entidx_lookup_writer_guid (prd->e.gv->entity_index, &wrguid);
|
||||||
if (wr)
|
if (wr)
|
||||||
{
|
{
|
||||||
ddsrt_mutex_lock (&wr->e.lock);
|
ddsrt_mutex_lock (&wr->e.lock);
|
||||||
|
@ -4899,7 +4845,7 @@ static void gc_delete_proxy_writer (struct gcreq *gcreq)
|
||||||
struct pwr_rd_match *m = ddsrt_avl_root_non_empty (&pwr_readers_treedef, &pwr->readers);
|
struct pwr_rd_match *m = ddsrt_avl_root_non_empty (&pwr_readers_treedef, &pwr->readers);
|
||||||
ddsrt_avl_delete (&pwr_readers_treedef, &pwr->readers, m);
|
ddsrt_avl_delete (&pwr_readers_treedef, &pwr->readers, m);
|
||||||
reader_drop_connection (&m->rd_guid, pwr);
|
reader_drop_connection (&m->rd_guid, pwr);
|
||||||
update_reader_init_acknack_count (&pwr->e.gv->logconfig, pwr->e.gv->guid_hash, &m->rd_guid, m->count);
|
update_reader_init_acknack_count (&pwr->e.gv->logconfig, pwr->e.gv->entity_index, &m->rd_guid, m->count);
|
||||||
free_pwr_rd_match (m);
|
free_pwr_rd_match (m);
|
||||||
}
|
}
|
||||||
local_reader_ary_fini (&pwr->rdary);
|
local_reader_ary_fini (&pwr->rdary);
|
||||||
|
@ -4920,7 +4866,7 @@ int delete_proxy_writer (struct q_globals *gv, const struct ddsi_guid *guid, nn_
|
||||||
GVLOGDISC ("delete_proxy_writer ("PGUIDFMT") ", PGUID (*guid));
|
GVLOGDISC ("delete_proxy_writer ("PGUIDFMT") ", PGUID (*guid));
|
||||||
|
|
||||||
ddsrt_mutex_lock (&gv->lock);
|
ddsrt_mutex_lock (&gv->lock);
|
||||||
if ((pwr = ephash_lookup_proxy_writer_guid (gv->guid_hash, guid)) == NULL)
|
if ((pwr = entidx_lookup_proxy_writer_guid (gv->entity_index, guid)) == NULL)
|
||||||
{
|
{
|
||||||
ddsrt_mutex_unlock (&gv->lock);
|
ddsrt_mutex_unlock (&gv->lock);
|
||||||
GVLOGDISC ("- unknown\n");
|
GVLOGDISC ("- unknown\n");
|
||||||
|
@ -4934,7 +4880,7 @@ int delete_proxy_writer (struct q_globals *gv, const struct ddsi_guid *guid, nn_
|
||||||
local_reader_ary_setinvalid (&pwr->rdary);
|
local_reader_ary_setinvalid (&pwr->rdary);
|
||||||
GVLOGDISC ("- deleting\n");
|
GVLOGDISC ("- deleting\n");
|
||||||
builtintopic_write (gv->builtin_topic_interface, &pwr->e, timestamp, false);
|
builtintopic_write (gv->builtin_topic_interface, &pwr->e, timestamp, false);
|
||||||
ephash_remove_proxy_writer_guid (gv->guid_hash, pwr);
|
entidx_remove_proxy_writer_guid (gv->entity_index, pwr);
|
||||||
ddsrt_mutex_unlock (&gv->lock);
|
ddsrt_mutex_unlock (&gv->lock);
|
||||||
if (pwr->c.xqos->liveliness.lease_duration != T_NEVER &&
|
if (pwr->c.xqos->liveliness.lease_duration != T_NEVER &&
|
||||||
pwr->c.xqos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_TOPIC)
|
pwr->c.xqos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_TOPIC)
|
||||||
|
@ -4973,9 +4919,9 @@ void proxy_writer_set_alive_may_unlock (struct proxy_writer *pwr, bool notify)
|
||||||
assert (!pwr->alive);
|
assert (!pwr->alive);
|
||||||
|
|
||||||
/* check that proxy writer still exists (when deleting it is removed from guid hash) */
|
/* check that proxy writer still exists (when deleting it is removed from guid hash) */
|
||||||
if (ephash_lookup_proxy_writer_guid (pwr->e.gv->guid_hash, &pwr->e.guid) == NULL)
|
if (entidx_lookup_proxy_writer_guid (pwr->e.gv->entity_index, &pwr->e.guid) == NULL)
|
||||||
{
|
{
|
||||||
ELOGDISC (pwr, "proxy_writer_set_alive_may_unlock("PGUIDFMT") - not in guid_hash, pwr deleting\n", PGUID (pwr->e.guid));
|
ELOGDISC (pwr, "proxy_writer_set_alive_may_unlock("PGUIDFMT") - not in entity index, pwr deleting\n", PGUID (pwr->e.guid));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5017,7 +4963,7 @@ int proxy_writer_set_notalive (struct proxy_writer *pwr, bool notify)
|
||||||
void proxy_writer_set_notalive_guid (struct q_globals *gv, const struct ddsi_guid *pwrguid, bool notify)
|
void proxy_writer_set_notalive_guid (struct q_globals *gv, const struct ddsi_guid *pwrguid, bool notify)
|
||||||
{
|
{
|
||||||
struct proxy_writer *pwr;
|
struct proxy_writer *pwr;
|
||||||
if ((pwr = ephash_lookup_proxy_writer_guid (gv->guid_hash, pwrguid)) == NULL)
|
if ((pwr = entidx_lookup_proxy_writer_guid (gv->entity_index, pwrguid)) == NULL)
|
||||||
GVLOGDISC (" "PGUIDFMT"?\n", PGUID (*pwrguid));
|
GVLOGDISC (" "PGUIDFMT"?\n", PGUID (*pwrguid));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -5042,9 +4988,9 @@ int new_proxy_reader (struct q_globals *gv, const struct ddsi_guid *ppguid, cons
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
assert (!is_writer_entityid (guid->entityid));
|
assert (!is_writer_entityid (guid->entityid));
|
||||||
assert (ephash_lookup_proxy_reader_guid (gv->guid_hash, guid) == NULL);
|
assert (entidx_lookup_proxy_reader_guid (gv->entity_index, guid) == NULL);
|
||||||
|
|
||||||
if ((proxypp = ephash_lookup_proxy_participant_guid (gv->guid_hash, ppguid)) == NULL)
|
if ((proxypp = entidx_lookup_proxy_participant_guid (gv->entity_index, ppguid)) == NULL)
|
||||||
{
|
{
|
||||||
GVWARNING ("new_proxy_reader("PGUIDFMT"): proxy participant unknown\n", PGUID (*guid));
|
GVWARNING ("new_proxy_reader("PGUIDFMT"): proxy participant unknown\n", PGUID (*guid));
|
||||||
return DDS_RETCODE_BAD_PARAMETER;
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
|
@ -5078,7 +5024,7 @@ int new_proxy_reader (struct q_globals *gv, const struct ddsi_guid *ppguid, cons
|
||||||
|
|
||||||
/* locking the entity prevents matching while the built-in topic hasn't been published yet */
|
/* locking the entity prevents matching while the built-in topic hasn't been published yet */
|
||||||
ddsrt_mutex_lock (&prd->e.lock);
|
ddsrt_mutex_lock (&prd->e.lock);
|
||||||
ephash_insert_proxy_reader_guid (gv->guid_hash, prd);
|
entidx_insert_proxy_reader_guid (gv->entity_index, prd);
|
||||||
builtintopic_write (gv->builtin_topic_interface, &prd->e, timestamp, true);
|
builtintopic_write (gv->builtin_topic_interface, &prd->e, timestamp, true);
|
||||||
ddsrt_mutex_unlock (&prd->e.lock);
|
ddsrt_mutex_unlock (&prd->e.lock);
|
||||||
|
|
||||||
|
@ -5111,7 +5057,7 @@ static void proxy_reader_set_delete_and_ack_all_messages (struct proxy_reader *p
|
||||||
}
|
}
|
||||||
|
|
||||||
ddsrt_mutex_unlock (&prd->e.lock);
|
ddsrt_mutex_unlock (&prd->e.lock);
|
||||||
if ((wr = ephash_lookup_writer_guid (prd->e.gv->guid_hash, &wrguid)) != NULL)
|
if ((wr = entidx_lookup_writer_guid (prd->e.gv->entity_index, &wrguid)) != NULL)
|
||||||
{
|
{
|
||||||
struct whc_node *deferred_free_list = NULL;
|
struct whc_node *deferred_free_list = NULL;
|
||||||
struct wr_prd_match *m_wr;
|
struct wr_prd_match *m_wr;
|
||||||
|
@ -5158,14 +5104,14 @@ int delete_proxy_reader (struct q_globals *gv, const struct ddsi_guid *guid, nn_
|
||||||
(void)isimplicit;
|
(void)isimplicit;
|
||||||
GVLOGDISC ("delete_proxy_reader ("PGUIDFMT") ", PGUID (*guid));
|
GVLOGDISC ("delete_proxy_reader ("PGUIDFMT") ", PGUID (*guid));
|
||||||
ddsrt_mutex_lock (&gv->lock);
|
ddsrt_mutex_lock (&gv->lock);
|
||||||
if ((prd = ephash_lookup_proxy_reader_guid (gv->guid_hash, guid)) == NULL)
|
if ((prd = entidx_lookup_proxy_reader_guid (gv->entity_index, guid)) == NULL)
|
||||||
{
|
{
|
||||||
ddsrt_mutex_unlock (&gv->lock);
|
ddsrt_mutex_unlock (&gv->lock);
|
||||||
GVLOGDISC ("- unknown\n");
|
GVLOGDISC ("- unknown\n");
|
||||||
return DDS_RETCODE_BAD_PARAMETER;
|
return DDS_RETCODE_BAD_PARAMETER;
|
||||||
}
|
}
|
||||||
builtintopic_write (gv->builtin_topic_interface, &prd->e, timestamp, false);
|
builtintopic_write (gv->builtin_topic_interface, &prd->e, timestamp, false);
|
||||||
ephash_remove_proxy_reader_guid (gv->guid_hash, prd);
|
entidx_remove_proxy_reader_guid (gv->entity_index, prd);
|
||||||
ddsrt_mutex_unlock (&gv->lock);
|
ddsrt_mutex_unlock (&gv->lock);
|
||||||
GVLOGDISC ("- deleting\n");
|
GVLOGDISC ("- deleting\n");
|
||||||
|
|
||||||
|
|
|
@ -1,367 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
|
||||||
*
|
|
||||||
* This program and the accompanying materials are made available under the
|
|
||||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
|
||||||
* v. 1.0 which is available at
|
|
||||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
|
||||||
*/
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "dds/ddsrt/heap.h"
|
|
||||||
#include "dds/ddsrt/misc.h"
|
|
||||||
|
|
||||||
#include "dds/ddsrt/hopscotch.h"
|
|
||||||
#include "dds/ddsi/q_ephash.h"
|
|
||||||
#include "dds/ddsi/q_config.h"
|
|
||||||
#include "dds/ddsi/q_globals.h"
|
|
||||||
#include "dds/ddsi/q_entity.h"
|
|
||||||
#include "dds/ddsi/q_gc.h"
|
|
||||||
#include "dds/ddsi/q_rtps.h" /* guid_t */
|
|
||||||
#include "dds/ddsi/q_thread.h" /* for assert(thread is awake) */
|
|
||||||
|
|
||||||
struct ephash {
|
|
||||||
struct ddsrt_chh *hash;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint64_t unihashconsts[] = {
|
|
||||||
UINT64_C (16292676669999574021),
|
|
||||||
UINT64_C (10242350189706880077),
|
|
||||||
UINT64_C (12844332200329132887),
|
|
||||||
UINT64_C (16728792139623414127)
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint32_t hash_entity_guid (const struct entity_common *c)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
(uint32_t) (((((uint32_t) c->guid.prefix.u[0] + unihashconsts[0]) *
|
|
||||||
((uint32_t) c->guid.prefix.u[1] + unihashconsts[1])) +
|
|
||||||
(((uint32_t) c->guid.prefix.u[2] + unihashconsts[2]) *
|
|
||||||
((uint32_t) c->guid.entityid.u + unihashconsts[3])))
|
|
||||||
>> 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t hash_entity_guid_wrapper (const void *c)
|
|
||||||
{
|
|
||||||
return hash_entity_guid (c);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int entity_guid_eq (const struct entity_common *a, const struct entity_common *b)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
a->guid.prefix.u[0] == b->guid.prefix.u[0] && a->guid.prefix.u[1] == b->guid.prefix.u[1] &&
|
|
||||||
a->guid.prefix.u[2] == b->guid.prefix.u[2] && a->guid.entityid.u == b->guid.entityid.u;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int entity_guid_eq_wrapper (const void *a, const void *b)
|
|
||||||
{
|
|
||||||
return entity_guid_eq (a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gc_buckets_cb (struct gcreq *gcreq)
|
|
||||||
{
|
|
||||||
void *bs = gcreq->arg;
|
|
||||||
gcreq_free (gcreq);
|
|
||||||
ddsrt_free (bs);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gc_buckets (void *bs, void *varg)
|
|
||||||
{
|
|
||||||
struct q_globals *gv = varg;
|
|
||||||
struct gcreq *gcreq = gcreq_new (gv->gcreq_queue, gc_buckets_cb);
|
|
||||||
gcreq->arg = bs;
|
|
||||||
gcreq_enqueue (gcreq);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ephash *ephash_new (struct q_globals *gv)
|
|
||||||
{
|
|
||||||
struct ephash *ephash;
|
|
||||||
ephash = ddsrt_malloc (sizeof (*ephash));
|
|
||||||
ephash->hash = ddsrt_chh_new (32, hash_entity_guid_wrapper, entity_guid_eq_wrapper, gc_buckets, gv);
|
|
||||||
if (ephash->hash == NULL) {
|
|
||||||
ddsrt_free (ephash);
|
|
||||||
return NULL;
|
|
||||||
} else {
|
|
||||||
return ephash;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_free (struct ephash *ephash)
|
|
||||||
{
|
|
||||||
ddsrt_chh_free (ephash->hash);
|
|
||||||
ephash->hash = NULL;
|
|
||||||
ddsrt_free (ephash);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ephash_guid_insert (struct ephash *gh, struct entity_common *e)
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
x = ddsrt_chh_add (gh->hash, e);
|
|
||||||
(void)x;
|
|
||||||
assert (x);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ephash_guid_remove (struct ephash *gh, struct entity_common *e)
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
x = ddsrt_chh_remove (gh->hash, e);
|
|
||||||
(void)x;
|
|
||||||
assert (x);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *ephash_lookup_guid_untyped (const struct ephash *gh, const struct ddsi_guid *guid)
|
|
||||||
{
|
|
||||||
/* FIXME: could (now) require guid to be first in entity_common; entity_common already is first in entity */
|
|
||||||
struct entity_common e;
|
|
||||||
e.guid = *guid;
|
|
||||||
assert (thread_is_awake ());
|
|
||||||
return ddsrt_chh_lookup (gh->hash, &e);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *ephash_lookup_guid_int (const struct ephash *gh, const struct ddsi_guid *guid, enum entity_kind kind)
|
|
||||||
{
|
|
||||||
struct entity_common *res;
|
|
||||||
if ((res = ephash_lookup_guid_untyped (gh, guid)) != NULL && res->kind == kind)
|
|
||||||
return res;
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *ephash_lookup_guid (const struct ephash *gh, const struct ddsi_guid *guid, enum entity_kind kind)
|
|
||||||
{
|
|
||||||
return ephash_lookup_guid_int (gh, guid, kind);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_insert_participant_guid (struct ephash *gh, struct participant *pp)
|
|
||||||
{
|
|
||||||
ephash_guid_insert (gh, &pp->e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_insert_proxy_participant_guid (struct ephash *gh, struct proxy_participant *proxypp)
|
|
||||||
{
|
|
||||||
ephash_guid_insert (gh, &proxypp->e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_insert_writer_guid (struct ephash *gh, struct writer *wr)
|
|
||||||
{
|
|
||||||
ephash_guid_insert (gh, &wr->e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_insert_reader_guid (struct ephash *gh, struct reader *rd)
|
|
||||||
{
|
|
||||||
ephash_guid_insert (gh, &rd->e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_insert_proxy_writer_guid (struct ephash *gh, struct proxy_writer *pwr)
|
|
||||||
{
|
|
||||||
ephash_guid_insert (gh, &pwr->e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_insert_proxy_reader_guid (struct ephash *gh, struct proxy_reader *prd)
|
|
||||||
{
|
|
||||||
ephash_guid_insert (gh, &prd->e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_remove_participant_guid (struct ephash *gh, struct participant *pp)
|
|
||||||
{
|
|
||||||
ephash_guid_remove (gh, &pp->e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_remove_proxy_participant_guid (struct ephash *gh, struct proxy_participant *proxypp)
|
|
||||||
{
|
|
||||||
ephash_guid_remove (gh, &proxypp->e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_remove_writer_guid (struct ephash *gh, struct writer *wr)
|
|
||||||
{
|
|
||||||
ephash_guid_remove (gh, &wr->e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_remove_reader_guid (struct ephash *gh, struct reader *rd)
|
|
||||||
{
|
|
||||||
ephash_guid_remove (gh, &rd->e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_remove_proxy_writer_guid (struct ephash *gh, struct proxy_writer *pwr)
|
|
||||||
{
|
|
||||||
ephash_guid_remove (gh, &pwr->e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_remove_proxy_reader_guid (struct ephash *gh, struct proxy_reader *prd)
|
|
||||||
{
|
|
||||||
ephash_guid_remove (gh, &prd->e);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct participant *ephash_lookup_participant_guid (const struct ephash *gh, const struct ddsi_guid *guid)
|
|
||||||
{
|
|
||||||
assert (guid->entityid.u == NN_ENTITYID_PARTICIPANT);
|
|
||||||
assert (offsetof (struct participant, e) == 0);
|
|
||||||
return ephash_lookup_guid_int (gh, guid, EK_PARTICIPANT);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct proxy_participant *ephash_lookup_proxy_participant_guid (const struct ephash *gh, const struct ddsi_guid *guid)
|
|
||||||
{
|
|
||||||
assert (guid->entityid.u == NN_ENTITYID_PARTICIPANT);
|
|
||||||
assert (offsetof (struct proxy_participant, e) == 0);
|
|
||||||
return ephash_lookup_guid_int (gh, guid, EK_PROXY_PARTICIPANT);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct writer *ephash_lookup_writer_guid (const struct ephash *gh, const struct ddsi_guid *guid)
|
|
||||||
{
|
|
||||||
assert (is_writer_entityid (guid->entityid));
|
|
||||||
assert (offsetof (struct writer, e) == 0);
|
|
||||||
return ephash_lookup_guid_int (gh, guid, EK_WRITER);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct reader *ephash_lookup_reader_guid (const struct ephash *gh, const struct ddsi_guid *guid)
|
|
||||||
{
|
|
||||||
assert (is_reader_entityid (guid->entityid));
|
|
||||||
assert (offsetof (struct reader, e) == 0);
|
|
||||||
return ephash_lookup_guid_int (gh, guid, EK_READER);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct proxy_writer *ephash_lookup_proxy_writer_guid (const struct ephash *gh, const struct ddsi_guid *guid)
|
|
||||||
{
|
|
||||||
assert (is_writer_entityid (guid->entityid));
|
|
||||||
assert (offsetof (struct proxy_writer, e) == 0);
|
|
||||||
return ephash_lookup_guid_int (gh, guid, EK_PROXY_WRITER);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct proxy_reader *ephash_lookup_proxy_reader_guid (const struct ephash *gh, const struct ddsi_guid *guid)
|
|
||||||
{
|
|
||||||
assert (is_reader_entityid (guid->entityid));
|
|
||||||
assert (offsetof (struct proxy_reader, e) == 0);
|
|
||||||
return ephash_lookup_guid_int (gh, guid, EK_PROXY_READER);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enumeration */
|
|
||||||
|
|
||||||
static void ephash_enum_init_int (struct ephash_enum *st, const struct ephash *gh, enum entity_kind kind)
|
|
||||||
{
|
|
||||||
st->kind = kind;
|
|
||||||
st->cur = ddsrt_chh_iter_first (gh->hash, &st->it);
|
|
||||||
while (st->cur && st->cur->kind != st->kind)
|
|
||||||
st->cur = ddsrt_chh_iter_next (&st->it);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_enum_init (struct ephash_enum *st, const struct ephash *gh, enum entity_kind kind)
|
|
||||||
{
|
|
||||||
ephash_enum_init_int(st, gh, kind);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_enum_writer_init (struct ephash_enum_writer *st, const struct ephash *gh)
|
|
||||||
{
|
|
||||||
ephash_enum_init (&st->st, gh, EK_WRITER);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_enum_reader_init (struct ephash_enum_reader *st, const struct ephash *gh)
|
|
||||||
{
|
|
||||||
ephash_enum_init (&st->st, gh, EK_READER);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_enum_proxy_writer_init (struct ephash_enum_proxy_writer *st, const struct ephash *gh)
|
|
||||||
{
|
|
||||||
ephash_enum_init (&st->st, gh, EK_PROXY_WRITER);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_enum_proxy_reader_init (struct ephash_enum_proxy_reader *st, const struct ephash *gh)
|
|
||||||
{
|
|
||||||
ephash_enum_init (&st->st, gh, EK_PROXY_READER);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_enum_participant_init (struct ephash_enum_participant *st, const struct ephash *gh)
|
|
||||||
{
|
|
||||||
ephash_enum_init (&st->st, gh, EK_PARTICIPANT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_enum_proxy_participant_init (struct ephash_enum_proxy_participant *st, const struct ephash *gh)
|
|
||||||
{
|
|
||||||
ephash_enum_init (&st->st, gh, EK_PROXY_PARTICIPANT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *ephash_enum_next (struct ephash_enum *st)
|
|
||||||
{
|
|
||||||
void *res = st->cur;
|
|
||||||
if (st->cur)
|
|
||||||
{
|
|
||||||
st->cur = ddsrt_chh_iter_next (&st->it);
|
|
||||||
while (st->cur && st->cur->kind != st->kind)
|
|
||||||
st->cur = ddsrt_chh_iter_next (&st->it);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct writer *ephash_enum_writer_next (struct ephash_enum_writer *st)
|
|
||||||
{
|
|
||||||
assert (offsetof (struct writer, e) == 0);
|
|
||||||
return ephash_enum_next (&st->st);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct reader *ephash_enum_reader_next (struct ephash_enum_reader *st)
|
|
||||||
{
|
|
||||||
assert (offsetof (struct reader, e) == 0);
|
|
||||||
return ephash_enum_next (&st->st);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct proxy_writer *ephash_enum_proxy_writer_next (struct ephash_enum_proxy_writer *st)
|
|
||||||
{
|
|
||||||
assert (offsetof (struct proxy_writer, e) == 0);
|
|
||||||
return ephash_enum_next (&st->st);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct proxy_reader *ephash_enum_proxy_reader_next (struct ephash_enum_proxy_reader *st)
|
|
||||||
{
|
|
||||||
assert (offsetof (struct proxy_reader, e) == 0);
|
|
||||||
return ephash_enum_next (&st->st);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct participant *ephash_enum_participant_next (struct ephash_enum_participant *st)
|
|
||||||
{
|
|
||||||
assert (offsetof (struct participant, e) == 0);
|
|
||||||
return ephash_enum_next (&st->st);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct proxy_participant *ephash_enum_proxy_participant_next (struct ephash_enum_proxy_participant *st)
|
|
||||||
{
|
|
||||||
assert (offsetof (struct proxy_participant, e) == 0);
|
|
||||||
return ephash_enum_next (&st->st);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_enum_fini (struct ephash_enum *st)
|
|
||||||
{
|
|
||||||
DDSRT_UNUSED_ARG(st);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_enum_writer_fini (struct ephash_enum_writer *st)
|
|
||||||
{
|
|
||||||
ephash_enum_fini (&st->st);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_enum_reader_fini (struct ephash_enum_reader *st)
|
|
||||||
{
|
|
||||||
ephash_enum_fini (&st->st);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_enum_proxy_writer_fini (struct ephash_enum_proxy_writer *st)
|
|
||||||
{
|
|
||||||
ephash_enum_fini (&st->st);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_enum_proxy_reader_fini (struct ephash_enum_proxy_reader *st)
|
|
||||||
{
|
|
||||||
ephash_enum_fini (&st->st);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_enum_participant_fini (struct ephash_enum_participant *st)
|
|
||||||
{
|
|
||||||
ephash_enum_fini (&st->st);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ephash_enum_proxy_participant_fini (struct ephash_enum_proxy_participant *st)
|
|
||||||
{
|
|
||||||
ephash_enum_fini (&st->st);
|
|
||||||
}
|
|
|
@ -21,14 +21,12 @@
|
||||||
#include "dds/ddsi/q_config.h"
|
#include "dds/ddsi/q_config.h"
|
||||||
#include "dds/ddsi/q_time.h"
|
#include "dds/ddsi/q_time.h"
|
||||||
#include "dds/ddsi/q_thread.h"
|
#include "dds/ddsi/q_thread.h"
|
||||||
#include "dds/ddsi/q_ephash.h"
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/ddsi/q_unused.h"
|
#include "dds/ddsi/q_unused.h"
|
||||||
#include "dds/ddsi/q_lease.h"
|
#include "dds/ddsi/q_lease.h"
|
||||||
#include "dds/ddsi/q_globals.h" /* for mattr, cattr */
|
#include "dds/ddsi/q_globals.h" /* for mattr, cattr */
|
||||||
#include "dds/ddsi/q_receive.h" /* for trigger_receive_threads */
|
#include "dds/ddsi/q_receive.h" /* for trigger_receive_threads */
|
||||||
|
|
||||||
#include "dds/ddsi/q_rtps.h" /* for guid_hash */
|
|
||||||
|
|
||||||
struct gcreq_queue {
|
struct gcreq_queue {
|
||||||
struct gcreq *first;
|
struct gcreq *first;
|
||||||
struct gcreq *last;
|
struct gcreq *last;
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include "dds/ddsi/q_ddsi_discovery.h"
|
#include "dds/ddsi/q_ddsi_discovery.h"
|
||||||
#include "dds/ddsi/q_radmin.h"
|
#include "dds/ddsi/q_radmin.h"
|
||||||
#include "dds/ddsi/q_thread.h"
|
#include "dds/ddsi/q_thread.h"
|
||||||
#include "dds/ddsi/q_ephash.h"
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/ddsi/q_lease.h"
|
#include "dds/ddsi/q_lease.h"
|
||||||
#include "dds/ddsi/q_gc.h"
|
#include "dds/ddsi/q_gc.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
|
@ -784,7 +784,7 @@ static void wait_for_receive_threads (struct q_globals *gv)
|
||||||
}
|
}
|
||||||
if (trigev)
|
if (trigev)
|
||||||
{
|
{
|
||||||
delete_xevent (trigev);
|
delete_xevent_callback (trigev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1089,7 +1089,7 @@ int rtps_init (struct q_globals *gv)
|
||||||
ddsrt_cond_init (&gv->participant_set_cond);
|
ddsrt_cond_init (&gv->participant_set_cond);
|
||||||
lease_management_init (gv);
|
lease_management_init (gv);
|
||||||
gv->deleted_participants = deleted_participants_admin_new (&gv->logconfig, gv->config.prune_deleted_ppant.delay);
|
gv->deleted_participants = deleted_participants_admin_new (&gv->logconfig, gv->config.prune_deleted_ppant.delay);
|
||||||
gv->guid_hash = ephash_new (gv);
|
gv->entity_index = entity_index_new (gv);
|
||||||
|
|
||||||
ddsrt_mutex_init (&gv->privileged_pp_lock);
|
ddsrt_mutex_init (&gv->privileged_pp_lock);
|
||||||
gv->privileged_pp = NULL;
|
gv->privileged_pp = NULL;
|
||||||
|
@ -1408,8 +1408,8 @@ err_unicast_sockets:
|
||||||
ddsrt_mutex_destroy (&gv->spdp_lock);
|
ddsrt_mutex_destroy (&gv->spdp_lock);
|
||||||
ddsrt_mutex_destroy (&gv->lock);
|
ddsrt_mutex_destroy (&gv->lock);
|
||||||
ddsrt_mutex_destroy (&gv->privileged_pp_lock);
|
ddsrt_mutex_destroy (&gv->privileged_pp_lock);
|
||||||
ephash_free (gv->guid_hash);
|
entity_index_free (gv->entity_index);
|
||||||
gv->guid_hash = NULL;
|
gv->entity_index = NULL;
|
||||||
deleted_participants_admin_free (gv->deleted_participants);
|
deleted_participants_admin_free (gv->deleted_participants);
|
||||||
lease_management_term (gv);
|
lease_management_term (gv);
|
||||||
ddsrt_cond_destroy (&gv->participant_set_cond);
|
ddsrt_cond_destroy (&gv->participant_set_cond);
|
||||||
|
@ -1590,26 +1590,26 @@ void rtps_stop (struct q_globals *gv)
|
||||||
ddsrt_mutex_destroy (&gv->spdp_lock);
|
ddsrt_mutex_destroy (&gv->spdp_lock);
|
||||||
|
|
||||||
{
|
{
|
||||||
struct ephash_enum_proxy_participant est;
|
struct entidx_enum_proxy_participant est;
|
||||||
struct proxy_participant *proxypp;
|
struct proxy_participant *proxypp;
|
||||||
const nn_wctime_t tnow = now();
|
const nn_wctime_t tnow = now();
|
||||||
/* Clean up proxy readers, proxy writers and proxy
|
/* Clean up proxy readers, proxy writers and proxy
|
||||||
participants. Deleting a proxy participants deletes all its
|
participants. Deleting a proxy participants deletes all its
|
||||||
readers and writers automatically */
|
readers and writers automatically */
|
||||||
thread_state_awake (ts1, gv);
|
thread_state_awake (ts1, gv);
|
||||||
ephash_enum_proxy_participant_init (&est, gv->guid_hash);
|
entidx_enum_proxy_participant_init (&est, gv->entity_index);
|
||||||
while ((proxypp = ephash_enum_proxy_participant_next (&est)) != NULL)
|
while ((proxypp = entidx_enum_proxy_participant_next (&est)) != NULL)
|
||||||
{
|
{
|
||||||
delete_proxy_participant_by_guid (gv, &proxypp->e.guid, tnow, 1);
|
delete_proxy_participant_by_guid (gv, &proxypp->e.guid, tnow, 1);
|
||||||
}
|
}
|
||||||
ephash_enum_proxy_participant_fini (&est);
|
entidx_enum_proxy_participant_fini (&est);
|
||||||
thread_state_asleep (ts1);
|
thread_state_asleep (ts1);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
struct ephash_enum_writer est_wr;
|
struct entidx_enum_writer est_wr;
|
||||||
struct ephash_enum_reader est_rd;
|
struct entidx_enum_reader est_rd;
|
||||||
struct ephash_enum_participant est_pp;
|
struct entidx_enum_participant est_pp;
|
||||||
struct participant *pp;
|
struct participant *pp;
|
||||||
struct writer *wr;
|
struct writer *wr;
|
||||||
struct reader *rd;
|
struct reader *rd;
|
||||||
|
@ -1619,28 +1619,28 @@ void rtps_stop (struct q_globals *gv)
|
||||||
out. FIXME: need to keep xevent thread alive for a while
|
out. FIXME: need to keep xevent thread alive for a while
|
||||||
longer. */
|
longer. */
|
||||||
thread_state_awake (ts1, gv);
|
thread_state_awake (ts1, gv);
|
||||||
ephash_enum_writer_init (&est_wr, gv->guid_hash);
|
entidx_enum_writer_init (&est_wr, gv->entity_index);
|
||||||
while ((wr = ephash_enum_writer_next (&est_wr)) != NULL)
|
while ((wr = entidx_enum_writer_next (&est_wr)) != NULL)
|
||||||
{
|
{
|
||||||
if (!is_builtin_entityid (wr->e.guid.entityid, NN_VENDORID_ECLIPSE))
|
if (!is_builtin_entityid (wr->e.guid.entityid, NN_VENDORID_ECLIPSE))
|
||||||
delete_writer_nolinger (gv, &wr->e.guid);
|
delete_writer_nolinger (gv, &wr->e.guid);
|
||||||
}
|
}
|
||||||
ephash_enum_writer_fini (&est_wr);
|
entidx_enum_writer_fini (&est_wr);
|
||||||
thread_state_awake_to_awake_no_nest (ts1);
|
thread_state_awake_to_awake_no_nest (ts1);
|
||||||
ephash_enum_reader_init (&est_rd, gv->guid_hash);
|
entidx_enum_reader_init (&est_rd, gv->entity_index);
|
||||||
while ((rd = ephash_enum_reader_next (&est_rd)) != NULL)
|
while ((rd = entidx_enum_reader_next (&est_rd)) != NULL)
|
||||||
{
|
{
|
||||||
if (!is_builtin_entityid (rd->e.guid.entityid, NN_VENDORID_ECLIPSE))
|
if (!is_builtin_entityid (rd->e.guid.entityid, NN_VENDORID_ECLIPSE))
|
||||||
delete_reader (gv, &rd->e.guid);
|
delete_reader (gv, &rd->e.guid);
|
||||||
}
|
}
|
||||||
ephash_enum_reader_fini (&est_rd);
|
entidx_enum_reader_fini (&est_rd);
|
||||||
thread_state_awake_to_awake_no_nest (ts1);
|
thread_state_awake_to_awake_no_nest (ts1);
|
||||||
ephash_enum_participant_init (&est_pp, gv->guid_hash);
|
entidx_enum_participant_init (&est_pp, gv->entity_index);
|
||||||
while ((pp = ephash_enum_participant_next (&est_pp)) != NULL)
|
while ((pp = entidx_enum_participant_next (&est_pp)) != NULL)
|
||||||
{
|
{
|
||||||
delete_participant (gv, &pp->e.guid);
|
delete_participant (gv, &pp->e.guid);
|
||||||
}
|
}
|
||||||
ephash_enum_participant_fini (&est_pp);
|
entidx_enum_participant_fini (&est_pp);
|
||||||
thread_state_asleep (ts1);
|
thread_state_asleep (ts1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1751,8 +1751,8 @@ void rtps_fini (struct q_globals *gv)
|
||||||
|
|
||||||
ddsi_tkmap_free (gv->m_tkmap);
|
ddsi_tkmap_free (gv->m_tkmap);
|
||||||
|
|
||||||
ephash_free (gv->guid_hash);
|
entity_index_free (gv->entity_index);
|
||||||
gv->guid_hash = NULL;
|
gv->entity_index = NULL;
|
||||||
deleted_participants_admin_free (gv->deleted_participants);
|
deleted_participants_admin_free (gv->deleted_participants);
|
||||||
lease_management_term (gv);
|
lease_management_term (gv);
|
||||||
ddsrt_mutex_destroy (&gv->participant_set_lock);
|
ddsrt_mutex_destroy (&gv->participant_set_lock);
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include "dds/ddsi/q_addrset.h"
|
#include "dds/ddsi/q_addrset.h"
|
||||||
#include "dds/ddsi/q_ddsi_discovery.h"
|
#include "dds/ddsi/q_ddsi_discovery.h"
|
||||||
#include "dds/ddsi/q_radmin.h"
|
#include "dds/ddsi/q_radmin.h"
|
||||||
#include "dds/ddsi/q_ephash.h"
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
#include "dds/ddsi/q_globals.h"
|
#include "dds/ddsi/q_globals.h"
|
||||||
#include "dds/ddsi/q_xmsg.h"
|
#include "dds/ddsi/q_xmsg.h"
|
||||||
|
@ -262,8 +262,8 @@ int64_t check_and_handle_lease_expiration (struct q_globals *gv, nn_etime_t tnow
|
||||||
if (k == EK_PROXY_PARTICIPANT)
|
if (k == EK_PROXY_PARTICIPANT)
|
||||||
{
|
{
|
||||||
struct proxy_participant *proxypp;
|
struct proxy_participant *proxypp;
|
||||||
if ((proxypp = ephash_lookup_proxy_participant_guid (gv->guid_hash, &g)) != NULL &&
|
if ((proxypp = entidx_lookup_proxy_participant_guid (gv->entity_index, &g)) != NULL &&
|
||||||
ephash_lookup_proxy_participant_guid (gv->guid_hash, &proxypp->privileged_pp_guid) != NULL)
|
entidx_lookup_proxy_participant_guid (gv->entity_index, &proxypp->privileged_pp_guid) != NULL)
|
||||||
{
|
{
|
||||||
GVLOGDISC ("but postponing because privileged pp "PGUIDFMT" is still live\n", PGUID (proxypp->privileged_pp_guid));
|
GVLOGDISC ("but postponing because privileged pp "PGUIDFMT" is still live\n", PGUID (proxypp->privileged_pp_guid));
|
||||||
l->tsched = add_duration_to_etime (tnowE, 200 * T_MILLISECOND);
|
l->tsched = add_duration_to_etime (tnowE, 200 * T_MILLISECOND);
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
#include "dds/ddsi/q_ddsi_discovery.h"
|
#include "dds/ddsi/q_ddsi_discovery.h"
|
||||||
#include "dds/ddsi/q_radmin.h"
|
#include "dds/ddsi/q_radmin.h"
|
||||||
#include "dds/ddsi/q_thread.h"
|
#include "dds/ddsi/q_thread.h"
|
||||||
#include "dds/ddsi/q_ephash.h"
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/ddsi/q_lease.h"
|
#include "dds/ddsi/q_lease.h"
|
||||||
#include "dds/ddsi/q_gc.h"
|
#include "dds/ddsi/q_gc.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
|
@ -282,7 +282,7 @@ static int valid_NackFrag (NackFrag_t *msg, size_t size, int byteswap)
|
||||||
|
|
||||||
static void set_sampleinfo_proxy_writer (struct nn_rsample_info *sampleinfo, ddsi_guid_t *pwr_guid)
|
static void set_sampleinfo_proxy_writer (struct nn_rsample_info *sampleinfo, ddsi_guid_t *pwr_guid)
|
||||||
{
|
{
|
||||||
struct proxy_writer * pwr = ephash_lookup_proxy_writer_guid (sampleinfo->rst->gv->guid_hash, pwr_guid);
|
struct proxy_writer * pwr = entidx_lookup_proxy_writer_guid (sampleinfo->rst->gv->entity_index, pwr_guid);
|
||||||
sampleinfo->pwr = pwr;
|
sampleinfo->pwr = pwr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -726,7 +726,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((wr = ephash_lookup_writer_guid (rst->gv->guid_hash, &dst)) == NULL)
|
if ((wr = entidx_lookup_writer_guid (rst->gv->entity_index, &dst)) == NULL)
|
||||||
{
|
{
|
||||||
RSTTRACE (" "PGUIDFMT" -> "PGUIDFMT"?)", PGUID (src), PGUID (dst));
|
RSTTRACE (" "PGUIDFMT" -> "PGUIDFMT"?)", PGUID (src), PGUID (dst));
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -735,7 +735,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac
|
||||||
the normal pure ack steady state. If (a big "if"!) this shows up
|
the normal pure ack steady state. If (a big "if"!) this shows up
|
||||||
as a significant portion of the time, we can always rewrite it to
|
as a significant portion of the time, we can always rewrite it to
|
||||||
only retrieve it when needed. */
|
only retrieve it when needed. */
|
||||||
if ((prd = ephash_lookup_proxy_reader_guid (rst->gv->guid_hash, &src)) == NULL)
|
if ((prd = entidx_lookup_proxy_reader_guid (rst->gv->entity_index, &src)) == NULL)
|
||||||
{
|
{
|
||||||
RSTTRACE (" "PGUIDFMT"? -> "PGUIDFMT")", PGUID (src), PGUID (dst));
|
RSTTRACE (" "PGUIDFMT"? -> "PGUIDFMT")", PGUID (src), PGUID (dst));
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1192,7 +1192,7 @@ static int handle_Heartbeat (struct receiver_state *rst, nn_etime_t tnow, struct
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pwr = ephash_lookup_proxy_writer_guid (rst->gv->guid_hash, &src)) == NULL)
|
if ((pwr = entidx_lookup_proxy_writer_guid (rst->gv->entity_index, &src)) == NULL)
|
||||||
{
|
{
|
||||||
RSTTRACE (PGUIDFMT"? -> "PGUIDFMT")", PGUID (src), PGUID (dst));
|
RSTTRACE (PGUIDFMT"? -> "PGUIDFMT")", PGUID (src), PGUID (dst));
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1370,7 +1370,7 @@ static int handle_HeartbeatFrag (struct receiver_state *rst, UNUSED_ARG(nn_etime
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pwr = ephash_lookup_proxy_writer_guid (rst->gv->guid_hash, &src)) == NULL)
|
if ((pwr = entidx_lookup_proxy_writer_guid (rst->gv->entity_index, &src)) == NULL)
|
||||||
{
|
{
|
||||||
RSTTRACE (" "PGUIDFMT"? -> "PGUIDFMT")", PGUID (src), PGUID (dst));
|
RSTTRACE (" "PGUIDFMT"? -> "PGUIDFMT")", PGUID (src), PGUID (dst));
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1495,7 +1495,7 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((wr = ephash_lookup_writer_guid (rst->gv->guid_hash, &dst)) == NULL)
|
if ((wr = entidx_lookup_writer_guid (rst->gv->entity_index, &dst)) == NULL)
|
||||||
{
|
{
|
||||||
RSTTRACE (" "PGUIDFMT" -> "PGUIDFMT"?)", PGUID (src), PGUID (dst));
|
RSTTRACE (" "PGUIDFMT" -> "PGUIDFMT"?)", PGUID (src), PGUID (dst));
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1504,7 +1504,7 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N
|
||||||
the normal pure ack steady state. If (a big "if"!) this shows up
|
the normal pure ack steady state. If (a big "if"!) this shows up
|
||||||
as a significant portion of the time, we can always rewrite it to
|
as a significant portion of the time, we can always rewrite it to
|
||||||
only retrieve it when needed. */
|
only retrieve it when needed. */
|
||||||
if ((prd = ephash_lookup_proxy_reader_guid (rst->gv->guid_hash, &src)) == NULL)
|
if ((prd = entidx_lookup_proxy_reader_guid (rst->gv->entity_index, &src)) == NULL)
|
||||||
{
|
{
|
||||||
RSTTRACE (" "PGUIDFMT"? -> "PGUIDFMT")", PGUID (src), PGUID (dst));
|
RSTTRACE (" "PGUIDFMT"? -> "PGUIDFMT")", PGUID (src), PGUID (dst));
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1612,7 +1612,7 @@ static int handle_InfoDST (struct receiver_state *rst, const InfoDST_t *msg, con
|
||||||
ddsi_guid_t dst;
|
ddsi_guid_t dst;
|
||||||
dst.prefix = rst->dst_guid_prefix;
|
dst.prefix = rst->dst_guid_prefix;
|
||||||
dst.entityid = to_entityid(NN_ENTITYID_PARTICIPANT);
|
dst.entityid = to_entityid(NN_ENTITYID_PARTICIPANT);
|
||||||
rst->forme = (ephash_lookup_participant_guid (rst->gv->guid_hash, &dst) != NULL ||
|
rst->forme = (entidx_lookup_participant_guid (rst->gv->entity_index, &dst) != NULL ||
|
||||||
is_deleted_participant_guid (rst->gv->deleted_participants, &dst, DPG_LOCAL));
|
is_deleted_participant_guid (rst->gv->deleted_participants, &dst, DPG_LOCAL));
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1759,7 +1759,7 @@ static int handle_Gap (struct receiver_state *rst, nn_etime_t tnow, struct nn_rm
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pwr = ephash_lookup_proxy_writer_guid (rst->gv->guid_hash, &src)) == NULL)
|
if ((pwr = entidx_lookup_proxy_writer_guid (rst->gv->entity_index, &src)) == NULL)
|
||||||
{
|
{
|
||||||
RSTTRACE (""PGUIDFMT"? -> "PGUIDFMT")", PGUID (src), PGUID (dst));
|
RSTTRACE (""PGUIDFMT"? -> "PGUIDFMT")", PGUID (src), PGUID (dst));
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1992,7 +1992,7 @@ static struct reader *proxy_writer_first_in_sync_reader (struct proxy_writer *pw
|
||||||
struct pwr_rd_match *m;
|
struct pwr_rd_match *m;
|
||||||
struct reader *rd;
|
struct reader *rd;
|
||||||
for (m = ddsrt_avl_iter_first (&pwr_readers_treedef, &pwr->readers, it); m != NULL; m = ddsrt_avl_iter_next (it))
|
for (m = ddsrt_avl_iter_first (&pwr_readers_treedef, &pwr->readers, it); m != NULL; m = ddsrt_avl_iter_next (it))
|
||||||
if (m->in_sync == PRMSS_SYNC && (rd = ephash_lookup_reader_guid (pwr->e.gv->guid_hash, &m->rd_guid)) != NULL)
|
if (m->in_sync == PRMSS_SYNC && (rd = entidx_lookup_reader_guid (pwr->e.gv->entity_index, &m->rd_guid)) != NULL)
|
||||||
return rd;
|
return rd;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2002,7 +2002,7 @@ static struct reader *proxy_writer_next_in_sync_reader (struct proxy_writer *pwr
|
||||||
struct pwr_rd_match *m;
|
struct pwr_rd_match *m;
|
||||||
struct reader *rd;
|
struct reader *rd;
|
||||||
for (m = ddsrt_avl_iter_next (it); m != NULL; m = ddsrt_avl_iter_next (it))
|
for (m = ddsrt_avl_iter_next (it); m != NULL; m = ddsrt_avl_iter_next (it))
|
||||||
if (m->in_sync == PRMSS_SYNC && (rd = ephash_lookup_reader_guid (pwr->e.gv->guid_hash, &m->rd_guid)) != NULL)
|
if (m->in_sync == PRMSS_SYNC && (rd = entidx_lookup_reader_guid (pwr->e.gv->entity_index, &m->rd_guid)) != NULL)
|
||||||
return rd;
|
return rd;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2080,7 +2080,7 @@ static int deliver_user_data (const struct nn_rsample_info *sampleinfo, const st
|
||||||
/* FIXME: should it be 0, local wall clock time or INVALID? */
|
/* FIXME: should it be 0, local wall clock time or INVALID? */
|
||||||
const nn_wctime_t tstamp = (sampleinfo->timestamp.v != NN_WCTIME_INVALID.v) ? sampleinfo->timestamp : ((nn_wctime_t) {0});
|
const nn_wctime_t tstamp = (sampleinfo->timestamp.v != NN_WCTIME_INVALID.v) ? sampleinfo->timestamp : ((nn_wctime_t) {0});
|
||||||
struct ddsi_writer_info wrinfo;
|
struct ddsi_writer_info wrinfo;
|
||||||
ddsi_make_writer_info (&wrinfo, &pwr->e, pwr->c.xqos);
|
ddsi_make_writer_info (&wrinfo, &pwr->e, pwr->c.xqos, statusinfo);
|
||||||
|
|
||||||
if (rdguid == NULL)
|
if (rdguid == NULL)
|
||||||
{
|
{
|
||||||
|
@ -2157,7 +2157,7 @@ static int deliver_user_data (const struct nn_rsample_info *sampleinfo, const st
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct reader *rd = ephash_lookup_reader_guid (gv->guid_hash, rdguid);
|
struct reader *rd = entidx_lookup_reader_guid (gv->entity_index, rdguid);
|
||||||
if (rd != NULL)
|
if (rd != NULL)
|
||||||
{
|
{
|
||||||
struct ddsi_serdata *payload;
|
struct ddsi_serdata *payload;
|
||||||
|
@ -2173,8 +2173,8 @@ static int deliver_user_data (const struct nn_rsample_info *sampleinfo, const st
|
||||||
if (pwr_locked) ddsrt_mutex_unlock (&pwr->e.lock);
|
if (pwr_locked) ddsrt_mutex_unlock (&pwr->e.lock);
|
||||||
dds_sleepfor (DDS_MSECS (1));
|
dds_sleepfor (DDS_MSECS (1));
|
||||||
if (pwr_locked) ddsrt_mutex_lock (&pwr->e.lock);
|
if (pwr_locked) ddsrt_mutex_lock (&pwr->e.lock);
|
||||||
if (ephash_lookup_reader_guid (gv->guid_hash, rdguid) == NULL ||
|
if (entidx_lookup_reader_guid (gv->entity_index, rdguid) == NULL ||
|
||||||
ephash_lookup_proxy_writer_guid (gv->guid_hash, &pwr->e.guid) == NULL)
|
entidx_lookup_proxy_writer_guid (gv->entity_index, &pwr->e.guid) == NULL)
|
||||||
{
|
{
|
||||||
/* give up when reader or proxy writer no longer accessible */
|
/* give up when reader or proxy writer no longer accessible */
|
||||||
break;
|
break;
|
||||||
|
@ -2860,7 +2860,7 @@ static int handle_submsg_sequence
|
||||||
/* "forme" is a whether the current submessage is intended for this
|
/* "forme" is a whether the current submessage is intended for this
|
||||||
instance of DDSI2 and is roughly equivalent to
|
instance of DDSI2 and is roughly equivalent to
|
||||||
(dst_prefix == 0) ||
|
(dst_prefix == 0) ||
|
||||||
(ephash_lookup_participant_guid(dst_prefix:1c1) != 0)
|
(entidx_lookup_participant_guid(dst_prefix:1c1) != 0)
|
||||||
they are only roughly equivalent because the second term can become
|
they are only roughly equivalent because the second term can become
|
||||||
false at any time. That's ok: it's real purpose is to filter out
|
false at any time. That's ok: it's real purpose is to filter out
|
||||||
discovery data accidentally sent by Cloud */
|
discovery data accidentally sent by Cloud */
|
||||||
|
@ -3361,7 +3361,7 @@ static void local_participant_set_fini (struct local_participant_set *lps)
|
||||||
|
|
||||||
static void rebuild_local_participant_set (struct thread_state1 * const ts1, struct q_globals *gv, struct local_participant_set *lps)
|
static void rebuild_local_participant_set (struct thread_state1 * const ts1, struct q_globals *gv, struct local_participant_set *lps)
|
||||||
{
|
{
|
||||||
struct ephash_enum_participant est;
|
struct entidx_enum_participant est;
|
||||||
struct participant *pp;
|
struct participant *pp;
|
||||||
unsigned nps_alloc;
|
unsigned nps_alloc;
|
||||||
GVTRACE ("pp set gen changed: local %"PRIu32" global %"PRIu32"\n", lps->gen, ddsrt_atomic_ld32 (&gv->participant_set_generation));
|
GVTRACE ("pp set gen changed: local %"PRIu32" global %"PRIu32"\n", lps->gen, ddsrt_atomic_ld32 (&gv->participant_set_generation));
|
||||||
|
@ -3375,8 +3375,8 @@ static void rebuild_local_participant_set (struct thread_state1 * const ts1, str
|
||||||
ddsrt_free (lps->ps);
|
ddsrt_free (lps->ps);
|
||||||
lps->nps = 0;
|
lps->nps = 0;
|
||||||
lps->ps = (nps_alloc == 0) ? NULL : ddsrt_malloc (nps_alloc * sizeof (*lps->ps));
|
lps->ps = (nps_alloc == 0) ? NULL : ddsrt_malloc (nps_alloc * sizeof (*lps->ps));
|
||||||
ephash_enum_participant_init (&est, gv->guid_hash);
|
entidx_enum_participant_init (&est, gv->entity_index);
|
||||||
while ((pp = ephash_enum_participant_next (&est)) != NULL)
|
while ((pp = entidx_enum_participant_next (&est)) != NULL)
|
||||||
{
|
{
|
||||||
if (lps->nps == nps_alloc)
|
if (lps->nps == nps_alloc)
|
||||||
{
|
{
|
||||||
|
@ -3384,7 +3384,7 @@ static void rebuild_local_participant_set (struct thread_state1 * const ts1, str
|
||||||
existing ones removed), so we may have to restart if it
|
existing ones removed), so we may have to restart if it
|
||||||
turns out we didn't allocate enough memory [an
|
turns out we didn't allocate enough memory [an
|
||||||
alternative would be to realloc on the fly]. */
|
alternative would be to realloc on the fly]. */
|
||||||
ephash_enum_participant_fini (&est);
|
entidx_enum_participant_fini (&est);
|
||||||
GVTRACE (" need more memory - restarting\n");
|
GVTRACE (" need more memory - restarting\n");
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
|
@ -3396,7 +3396,7 @@ static void rebuild_local_participant_set (struct thread_state1 * const ts1, str
|
||||||
lps->nps++;
|
lps->nps++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ephash_enum_participant_fini (&est);
|
entidx_enum_participant_fini (&est);
|
||||||
|
|
||||||
/* There is a (very small) probability of a participant
|
/* There is a (very small) probability of a participant
|
||||||
disappearing and new one appearing with the same socket while
|
disappearing and new one appearing with the same socket while
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "dds/ddsrt/avl.h"
|
#include "dds/ddsrt/avl.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/ddsi/q_addrset.h"
|
#include "dds/ddsi/q_addrset.h"
|
||||||
#include "dds/ddsi/q_xmsg.h"
|
#include "dds/ddsi/q_xmsg.h"
|
||||||
#include "dds/ddsi/q_bswap.h"
|
#include "dds/ddsi/q_bswap.h"
|
||||||
|
@ -202,7 +203,7 @@ struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, const stru
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct proxy_reader *prd;
|
struct proxy_reader *prd;
|
||||||
if ((prd = ephash_lookup_proxy_reader_guid (gv->guid_hash, prd_guid)) == NULL)
|
if ((prd = entidx_lookup_proxy_reader_guid (gv->entity_index, prd_guid)) == NULL)
|
||||||
{
|
{
|
||||||
ETRACE (wr, "writer_hbcontrol: wr "PGUIDFMT" unknown prd "PGUIDFMT"\n", PGUID (wr->e.guid), PGUID (*prd_guid));
|
ETRACE (wr, "writer_hbcontrol: wr "PGUIDFMT" unknown prd "PGUIDFMT"\n", PGUID (wr->e.guid), PGUID (*prd_guid));
|
||||||
nn_xmsg_free (msg);
|
nn_xmsg_free (msg);
|
||||||
|
@ -745,7 +746,7 @@ dds_return_t write_hb_liveliness (struct q_globals * const gv, struct ddsi_guid
|
||||||
struct whc_state whcst;
|
struct whc_state whcst;
|
||||||
struct thread_state1 * const ts1 = lookup_thread_state ();
|
struct thread_state1 * const ts1 = lookup_thread_state ();
|
||||||
thread_state_awake (ts1, gv);
|
thread_state_awake (ts1, gv);
|
||||||
struct writer *wr = ephash_lookup_writer_guid (gv->guid_hash, wr_guid);
|
struct writer *wr = entidx_lookup_writer_guid (gv->entity_index, wr_guid);
|
||||||
if (wr == NULL)
|
if (wr == NULL)
|
||||||
{
|
{
|
||||||
GVTRACE ("write_hb_liveliness("PGUIDFMT") - writer not found\n", PGUID (*wr_guid));
|
GVTRACE ("write_hb_liveliness("PGUIDFMT") - writer not found\n", PGUID (*wr_guid));
|
||||||
|
@ -979,10 +980,18 @@ static int insert_sample_in_whc (struct writer *wr, seqno_t seq, struct nn_plist
|
||||||
|
|
||||||
if (!do_insert)
|
if (!do_insert)
|
||||||
res = 0;
|
res = 0;
|
||||||
else if ((insres = whc_insert (wr->whc, writer_max_drop_seq (wr), seq, plist, serdata, tk)) < 0)
|
|
||||||
res = insres;
|
|
||||||
else
|
else
|
||||||
res = 1;
|
{
|
||||||
|
nn_mtime_t exp = NN_MTIME_NEVER;
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
/* Don't set expiry for samples with flags unregister or dispose, because these are required
|
||||||
|
* for sample lifecycle and should always be delivered to the reader so that is can clean up
|
||||||
|
* its history cache. */
|
||||||
|
if (wr->xqos->lifespan.duration != DDS_INFINITY && (serdata->statusinfo & (NN_STATUSINFO_UNREGISTER | NN_STATUSINFO_DISPOSE)) == 0)
|
||||||
|
exp = add_duration_to_mtime(serdata->twrite, wr->xqos->lifespan.duration);
|
||||||
|
#endif
|
||||||
|
res = ((insres = whc_insert (wr->whc, writer_max_drop_seq (wr), seq, exp, plist, serdata, tk)) < 0) ? insres : 1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (((wr->e.guid.entityid.u == NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER) ||
|
if (((wr->e.guid.entityid.u == NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER) ||
|
||||||
|
|
|
@ -21,7 +21,7 @@ extern inline void whc_return_sample (struct whc *whc, struct whc_borrowed_sampl
|
||||||
extern inline void whc_sample_iter_init (const struct whc *whc, struct whc_sample_iter *it);
|
extern inline void whc_sample_iter_init (const struct whc *whc, struct whc_sample_iter *it);
|
||||||
extern inline bool whc_sample_iter_borrow_next (struct whc_sample_iter *it, struct whc_borrowed_sample *sample);
|
extern inline bool whc_sample_iter_borrow_next (struct whc_sample_iter *it, struct whc_borrowed_sample *sample);
|
||||||
extern inline void whc_free (struct whc *whc);
|
extern inline void whc_free (struct whc *whc);
|
||||||
extern int whc_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk);
|
extern int whc_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, nn_mtime_t exp, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk);
|
||||||
extern unsigned whc_downgrade_to_volatile (struct whc *whc, struct whc_state *st);
|
extern unsigned whc_downgrade_to_volatile (struct whc *whc, struct whc_state *st);
|
||||||
extern unsigned whc_remove_acked_messages (struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list);
|
extern unsigned whc_remove_acked_messages (struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list);
|
||||||
extern void whc_free_deferred_free_list (struct whc *whc, struct whc_node *deferred_free_list);
|
extern void whc_free_deferred_free_list (struct whc *whc, struct whc_node *deferred_free_list);
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include "dds/ddsi/q_config.h"
|
#include "dds/ddsi/q_config.h"
|
||||||
#include "dds/ddsi/q_unused.h"
|
#include "dds/ddsi/q_unused.h"
|
||||||
#include "dds/ddsi/q_globals.h"
|
#include "dds/ddsi/q_globals.h"
|
||||||
#include "dds/ddsi/q_ephash.h"
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/ddsi/q_transmit.h"
|
#include "dds/ddsi/q_transmit.h"
|
||||||
#include "dds/ddsi/q_bswap.h"
|
#include "dds/ddsi/q_bswap.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
|
@ -95,6 +95,7 @@ struct xevent
|
||||||
struct {
|
struct {
|
||||||
void (*cb) (struct xevent *ev, void *arg, nn_mtime_t tnow);
|
void (*cb) (struct xevent *ev, void *arg, nn_mtime_t tnow);
|
||||||
void *arg;
|
void *arg;
|
||||||
|
bool executing;
|
||||||
} callback;
|
} callback;
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
@ -233,7 +234,7 @@ static void add_to_non_timed_xmit_list (struct xeventq *evq, struct xevent_nt *e
|
||||||
if (ev->kind == XEVK_MSG_REXMIT)
|
if (ev->kind == XEVK_MSG_REXMIT)
|
||||||
remember_msg (evq, ev);
|
remember_msg (evq, ev);
|
||||||
|
|
||||||
ddsrt_cond_signal (&evq->cond);
|
ddsrt_cond_broadcast (&evq->cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct xevent_nt *getnext_from_non_timed_xmit_list (struct xeventq *evq)
|
static struct xevent_nt *getnext_from_non_timed_xmit_list (struct xeventq *evq)
|
||||||
|
@ -317,6 +318,7 @@ void delete_xevent (struct xevent *ev)
|
||||||
{
|
{
|
||||||
struct xeventq *evq = ev->evq;
|
struct xeventq *evq = ev->evq;
|
||||||
ddsrt_mutex_lock (&evq->lock);
|
ddsrt_mutex_lock (&evq->lock);
|
||||||
|
assert (ev->kind != XEVK_CALLBACK || ev->u.callback.executing);
|
||||||
/* Can delete it only once, no matter how we implement it internally */
|
/* Can delete it only once, no matter how we implement it internally */
|
||||||
assert (ev->tsched.v != TSCHED_DELETE);
|
assert (ev->tsched.v != TSCHED_DELETE);
|
||||||
assert (TSCHED_DELETE < ev->tsched.v);
|
assert (TSCHED_DELETE < ev->tsched.v);
|
||||||
|
@ -332,27 +334,44 @@ void delete_xevent (struct xevent *ev)
|
||||||
}
|
}
|
||||||
/* TSCHED_DELETE is absolute minimum time, so chances are we need to
|
/* TSCHED_DELETE is absolute minimum time, so chances are we need to
|
||||||
wake up the thread. The superfluous signal is harmless. */
|
wake up the thread. The superfluous signal is harmless. */
|
||||||
ddsrt_cond_signal (&evq->cond);
|
ddsrt_cond_broadcast (&evq->cond);
|
||||||
ddsrt_mutex_unlock (&evq->lock);
|
ddsrt_mutex_unlock (&evq->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void delete_xevent_callback (struct xevent *ev)
|
||||||
|
{
|
||||||
|
struct xeventq *evq = ev->evq;
|
||||||
|
assert (ev->kind == XEVK_CALLBACK);
|
||||||
|
ddsrt_mutex_lock (&evq->lock);
|
||||||
|
if (ev->tsched.v != T_NEVER)
|
||||||
|
{
|
||||||
|
assert (ev->tsched.v != TSCHED_DELETE);
|
||||||
|
ddsrt_fibheap_delete (&evq_xevents_fhdef, &evq->xevents, ev);
|
||||||
|
ev->tsched.v = TSCHED_DELETE;
|
||||||
|
}
|
||||||
|
while (ev->u.callback.executing)
|
||||||
|
ddsrt_cond_wait (&evq->cond, &evq->lock);
|
||||||
|
ddsrt_mutex_unlock (&evq->lock);
|
||||||
|
free_xevent (evq, ev);
|
||||||
|
}
|
||||||
|
|
||||||
int resched_xevent_if_earlier (struct xevent *ev, nn_mtime_t tsched)
|
int resched_xevent_if_earlier (struct xevent *ev, nn_mtime_t tsched)
|
||||||
{
|
{
|
||||||
struct xeventq *evq = ev->evq;
|
struct xeventq *evq = ev->evq;
|
||||||
int is_resched;
|
int is_resched;
|
||||||
|
if (tsched.v == T_NEVER)
|
||||||
|
return 0;
|
||||||
ddsrt_mutex_lock (&evq->lock);
|
ddsrt_mutex_lock (&evq->lock);
|
||||||
assert (tsched.v != TSCHED_DELETE);
|
|
||||||
/* If you want to delete it, you to say so by calling the right
|
/* If you want to delete it, you to say so by calling the right
|
||||||
function. Don't want to reschedule an event marked for deletion,
|
function. Don't want to reschedule an event marked for deletion,
|
||||||
but with TSCHED_DELETE = MIN_INT64, tsched >= ev->tsched is
|
but with TSCHED_DELETE = MIN_INT64, tsched >= ev->tsched is
|
||||||
guaranteed to be false. */
|
guaranteed to be false. */
|
||||||
assert (tsched.v > TSCHED_DELETE);
|
assert (tsched.v != TSCHED_DELETE);
|
||||||
if (tsched.v >= ev->tsched.v)
|
if (tsched.v >= ev->tsched.v)
|
||||||
is_resched = 0;
|
is_resched = 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nn_mtime_t tbefore = earliest_in_xeventq (evq);
|
nn_mtime_t tbefore = earliest_in_xeventq (evq);
|
||||||
assert (tsched.v != T_NEVER);
|
|
||||||
if (ev->tsched.v != T_NEVER)
|
if (ev->tsched.v != T_NEVER)
|
||||||
{
|
{
|
||||||
ev->tsched = tsched;
|
ev->tsched = tsched;
|
||||||
|
@ -365,7 +384,7 @@ int resched_xevent_if_earlier (struct xevent *ev, nn_mtime_t tsched)
|
||||||
}
|
}
|
||||||
is_resched = 1;
|
is_resched = 1;
|
||||||
if (tsched.v < tbefore.v)
|
if (tsched.v < tbefore.v)
|
||||||
ddsrt_cond_signal (&evq->cond);
|
ddsrt_cond_broadcast (&evq->cond);
|
||||||
}
|
}
|
||||||
ddsrt_mutex_unlock (&evq->lock);
|
ddsrt_mutex_unlock (&evq->lock);
|
||||||
return is_resched;
|
return is_resched;
|
||||||
|
@ -407,13 +426,7 @@ static nn_mtime_t earliest_in_xeventq (struct xeventq *evq)
|
||||||
{
|
{
|
||||||
struct xevent *min;
|
struct xevent *min;
|
||||||
ASSERT_MUTEX_HELD (&evq->lock);
|
ASSERT_MUTEX_HELD (&evq->lock);
|
||||||
if ((min = ddsrt_fibheap_min (&evq_xevents_fhdef, &evq->xevents)) != NULL)
|
return ((min = ddsrt_fibheap_min (&evq_xevents_fhdef, &evq->xevents)) != NULL) ? min->tsched : NN_MTIME_NEVER;
|
||||||
return min->tsched;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nn_mtime_t r = { T_NEVER };
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qxev_insert (struct xevent *ev)
|
static void qxev_insert (struct xevent *ev)
|
||||||
|
@ -427,7 +440,7 @@ static void qxev_insert (struct xevent *ev)
|
||||||
nn_mtime_t tbefore = earliest_in_xeventq (evq);
|
nn_mtime_t tbefore = earliest_in_xeventq (evq);
|
||||||
ddsrt_fibheap_insert (&evq_xevents_fhdef, &evq->xevents, ev);
|
ddsrt_fibheap_insert (&evq_xevents_fhdef, &evq->xevents, ev);
|
||||||
if (ev->tsched.v < tbefore.v)
|
if (ev->tsched.v < tbefore.v)
|
||||||
ddsrt_cond_signal (&evq->cond);
|
ddsrt_cond_broadcast (&evq->cond);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,7 +516,7 @@ void xeventq_stop (struct xeventq *evq)
|
||||||
assert (evq->ts != NULL);
|
assert (evq->ts != NULL);
|
||||||
ddsrt_mutex_lock (&evq->lock);
|
ddsrt_mutex_lock (&evq->lock);
|
||||||
evq->terminate = 1;
|
evq->terminate = 1;
|
||||||
ddsrt_cond_signal (&evq->cond);
|
ddsrt_cond_broadcast (&evq->cond);
|
||||||
ddsrt_mutex_unlock (&evq->lock);
|
ddsrt_mutex_unlock (&evq->lock);
|
||||||
join_thread (evq->ts);
|
join_thread (evq->ts);
|
||||||
evq->ts = NULL;
|
evq->ts = NULL;
|
||||||
|
@ -514,22 +527,7 @@ void xeventq_free (struct xeventq *evq)
|
||||||
struct xevent *ev;
|
struct xevent *ev;
|
||||||
assert (evq->ts == NULL);
|
assert (evq->ts == NULL);
|
||||||
while ((ev = ddsrt_fibheap_extract_min (&evq_xevents_fhdef, &evq->xevents)) != NULL)
|
while ((ev = ddsrt_fibheap_extract_min (&evq_xevents_fhdef, &evq->xevents)) != NULL)
|
||||||
{
|
free_xevent (evq, ev);
|
||||||
if (ev->tsched.v == TSCHED_DELETE || ev->kind != XEVK_CALLBACK)
|
|
||||||
free_xevent (evq, ev);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ev->tsched.v = T_NEVER;
|
|
||||||
ev->u.callback.cb (ev, ev->u.callback.arg, ev->tsched);
|
|
||||||
if (ev->tsched.v != TSCHED_DELETE)
|
|
||||||
{
|
|
||||||
union { void *v; void (*f) (struct xevent *ev, void *arg, nn_mtime_t tnow); } fp;
|
|
||||||
fp.f = ev->u.callback.cb;
|
|
||||||
DDS_CWARNING (&evq->gv->logconfig, "xeventq_free: callback %p did not schedule deletion as required, deleting event anyway\n", fp.v);
|
|
||||||
delete_xevent (ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
struct nn_xpack *xp = nn_xpack_new (evq->tev_conn, evq->auxiliary_bandwidth_limit, false);
|
struct nn_xpack *xp = nn_xpack_new (evq->tev_conn, evq->auxiliary_bandwidth_limit, false);
|
||||||
|
@ -618,7 +616,7 @@ static void send_heartbeat_to_all_readers(struct nn_xpack *xp, struct xevent *ev
|
||||||
{
|
{
|
||||||
struct proxy_reader *prd;
|
struct proxy_reader *prd;
|
||||||
|
|
||||||
prd = ephash_lookup_proxy_reader_guid(wr->e.gv->guid_hash, &m->prd_guid);
|
prd = entidx_lookup_proxy_reader_guid(wr->e.gv->entity_index, &m->prd_guid);
|
||||||
if (prd)
|
if (prd)
|
||||||
{
|
{
|
||||||
ETRACE (wr, " heartbeat(wr "PGUIDFMT" rd "PGUIDFMT" %s) send, resched in %g s (min-ack %"PRId64", avail-seq %"PRId64")\n",
|
ETRACE (wr, " heartbeat(wr "PGUIDFMT" rd "PGUIDFMT" %s) send, resched in %g s (min-ack %"PRId64", avail-seq %"PRId64")\n",
|
||||||
|
@ -673,7 +671,7 @@ static void handle_xevk_heartbeat (struct nn_xpack *xp, struct xevent *ev, nn_mt
|
||||||
int hbansreq = 0;
|
int hbansreq = 0;
|
||||||
struct whc_state whcst;
|
struct whc_state whcst;
|
||||||
|
|
||||||
if ((wr = ephash_lookup_writer_guid (gv->guid_hash, &ev->u.heartbeat.wr_guid)) == NULL)
|
if ((wr = entidx_lookup_writer_guid (gv->entity_index, &ev->u.heartbeat.wr_guid)) == NULL)
|
||||||
{
|
{
|
||||||
GVTRACE("heartbeat(wr "PGUIDFMT") writer gone\n", PGUID (ev->u.heartbeat.wr_guid));
|
GVTRACE("heartbeat(wr "PGUIDFMT") writer gone\n", PGUID (ev->u.heartbeat.wr_guid));
|
||||||
return;
|
return;
|
||||||
|
@ -962,7 +960,7 @@ static void handle_xevk_acknack (struct nn_xpack *xp, struct xevent *ev, nn_mtim
|
||||||
struct pwr_rd_match *rwn;
|
struct pwr_rd_match *rwn;
|
||||||
nn_locator_t loc;
|
nn_locator_t loc;
|
||||||
|
|
||||||
if ((pwr = ephash_lookup_proxy_writer_guid (gv->guid_hash, &ev->u.acknack.pwr_guid)) == NULL)
|
if ((pwr = entidx_lookup_proxy_writer_guid (gv->entity_index, &ev->u.acknack.pwr_guid)) == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -981,7 +979,7 @@ static void handle_xevk_acknack (struct nn_xpack *xp, struct xevent *ev, nn_mtim
|
||||||
struct participant *pp = NULL;
|
struct participant *pp = NULL;
|
||||||
if (q_omg_security_enabled())
|
if (q_omg_security_enabled())
|
||||||
{
|
{
|
||||||
struct reader *rd = ephash_lookup_reader_guid(pwr->e.gv->guid_hash, &ev->u.acknack.rd_guid);
|
struct reader *rd = entidx_lookup_reader_guid(pwr->e.gv->entity_index, &ev->u.acknack.rd_guid);
|
||||||
if (rd)
|
if (rd)
|
||||||
pp = rd->c.pp;
|
pp = rd->c.pp;
|
||||||
}
|
}
|
||||||
|
@ -1104,7 +1102,7 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e
|
||||||
struct writer *spdp_wr;
|
struct writer *spdp_wr;
|
||||||
bool do_write;
|
bool do_write;
|
||||||
|
|
||||||
if ((pp = ephash_lookup_participant_guid (gv->guid_hash, &ev->u.spdp.pp_guid)) == NULL)
|
if ((pp = entidx_lookup_participant_guid (gv->entity_index, &ev->u.spdp.pp_guid)) == NULL)
|
||||||
{
|
{
|
||||||
GVTRACE ("handle_xevk_spdp "PGUIDFMT" - unknown guid\n", PGUID (ev->u.spdp.pp_guid));
|
GVTRACE ("handle_xevk_spdp "PGUIDFMT" - unknown guid\n", PGUID (ev->u.spdp.pp_guid));
|
||||||
if (ev->u.spdp.directed)
|
if (ev->u.spdp.directed)
|
||||||
|
@ -1132,7 +1130,7 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e
|
||||||
ddsi_guid_t guid;
|
ddsi_guid_t guid;
|
||||||
guid.prefix = ev->u.spdp.dest_proxypp_guid_prefix;
|
guid.prefix = ev->u.spdp.dest_proxypp_guid_prefix;
|
||||||
guid.entityid.u = NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER;
|
guid.entityid.u = NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER;
|
||||||
prd = ephash_lookup_proxy_reader_guid (gv->guid_hash, &guid);
|
prd = entidx_lookup_proxy_reader_guid (gv->entity_index, &guid);
|
||||||
do_write = (prd != NULL);
|
do_write = (prd != NULL);
|
||||||
if (!do_write)
|
if (!do_write)
|
||||||
GVTRACE ("xmit spdp: no proxy reader "PGUIDFMT"\n", PGUID (guid));
|
GVTRACE ("xmit spdp: no proxy reader "PGUIDFMT"\n", PGUID (guid));
|
||||||
|
@ -1217,7 +1215,7 @@ static void handle_xevk_pmd_update (struct thread_state1 * const ts1, struct nn_
|
||||||
dds_duration_t intv;
|
dds_duration_t intv;
|
||||||
nn_mtime_t tnext;
|
nn_mtime_t tnext;
|
||||||
|
|
||||||
if ((pp = ephash_lookup_participant_guid (gv->guid_hash, &ev->u.pmd_update.pp_guid)) == NULL)
|
if ((pp = entidx_lookup_participant_guid (gv->entity_index, &ev->u.pmd_update.pp_guid)) == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1255,27 +1253,46 @@ static void handle_xevk_delete_writer (UNUSED_ARG (struct nn_xpack *xp), struct
|
||||||
|
|
||||||
static void handle_individual_xevent (struct thread_state1 * const ts1, struct xevent *xev, struct nn_xpack *xp, nn_mtime_t tnow)
|
static void handle_individual_xevent (struct thread_state1 * const ts1, struct xevent *xev, struct nn_xpack *xp, nn_mtime_t tnow)
|
||||||
{
|
{
|
||||||
switch (xev->kind)
|
struct xeventq *xevq = xev->evq;
|
||||||
|
/* We relinquish the lock while processing the event, but require it
|
||||||
|
held for administrative work. */
|
||||||
|
ASSERT_MUTEX_HELD (&xevq->lock);
|
||||||
|
if (xev->kind == XEVK_CALLBACK)
|
||||||
{
|
{
|
||||||
case XEVK_HEARTBEAT:
|
xev->u.callback.executing = true;
|
||||||
handle_xevk_heartbeat (xp, xev, tnow);
|
ddsrt_mutex_unlock (&xevq->lock);
|
||||||
break;
|
xev->u.callback.cb (xev, xev->u.callback.arg, tnow);
|
||||||
case XEVK_ACKNACK:
|
ddsrt_mutex_lock (&xevq->lock);
|
||||||
handle_xevk_acknack (xp, xev, tnow);
|
xev->u.callback.executing = false;
|
||||||
break;
|
ddsrt_cond_broadcast (&xevq->cond);
|
||||||
case XEVK_SPDP:
|
|
||||||
handle_xevk_spdp (xp, xev, tnow);
|
|
||||||
break;
|
|
||||||
case XEVK_PMD_UPDATE:
|
|
||||||
handle_xevk_pmd_update (ts1, xp, xev, tnow);
|
|
||||||
break;
|
|
||||||
case XEVK_DELETE_WRITER:
|
|
||||||
handle_xevk_delete_writer (xp, xev, tnow);
|
|
||||||
break;
|
|
||||||
case XEVK_CALLBACK:
|
|
||||||
xev->u.callback.cb (xev, xev->u.callback.arg, tnow);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ddsrt_mutex_unlock (&xevq->lock);
|
||||||
|
switch (xev->kind)
|
||||||
|
{
|
||||||
|
case XEVK_HEARTBEAT:
|
||||||
|
handle_xevk_heartbeat (xp, xev, tnow);
|
||||||
|
break;
|
||||||
|
case XEVK_ACKNACK:
|
||||||
|
handle_xevk_acknack (xp, xev, tnow);
|
||||||
|
break;
|
||||||
|
case XEVK_SPDP:
|
||||||
|
handle_xevk_spdp (xp, xev, tnow);
|
||||||
|
break;
|
||||||
|
case XEVK_PMD_UPDATE:
|
||||||
|
handle_xevk_pmd_update (ts1, xp, xev, tnow);
|
||||||
|
break;
|
||||||
|
case XEVK_DELETE_WRITER:
|
||||||
|
handle_xevk_delete_writer (xp, xev, tnow);
|
||||||
|
break;
|
||||||
|
case XEVK_CALLBACK:
|
||||||
|
assert (0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ddsrt_mutex_lock (&xevq->lock);
|
||||||
|
}
|
||||||
|
ASSERT_MUTEX_HELD (&xevq->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_individual_xevent_nt (struct xevent_nt *xev, struct nn_xpack *xp)
|
static void handle_individual_xevent_nt (struct xevent_nt *xev, struct nn_xpack *xp)
|
||||||
|
@ -1299,20 +1316,8 @@ static void handle_timed_xevent (struct thread_state1 * const ts1, struct xevent
|
||||||
{
|
{
|
||||||
/* This function handles the individual xevent irrespective of
|
/* This function handles the individual xevent irrespective of
|
||||||
whether it is a "timed" or "non-timed" xevent */
|
whether it is a "timed" or "non-timed" xevent */
|
||||||
struct xeventq *xevq = xev->evq;
|
|
||||||
|
|
||||||
/* We relinquish the lock while processing the event, but require it
|
|
||||||
held for administrative work. */
|
|
||||||
ASSERT_MUTEX_HELD (&xevq->lock);
|
|
||||||
|
|
||||||
assert (xev->evq == xevq);
|
|
||||||
assert (xev->tsched.v != TSCHED_DELETE);
|
assert (xev->tsched.v != TSCHED_DELETE);
|
||||||
|
|
||||||
ddsrt_mutex_unlock (&xevq->lock);
|
|
||||||
handle_individual_xevent (ts1, xev, xp, tnow /* monotonic */);
|
handle_individual_xevent (ts1, xev, xp, tnow /* monotonic */);
|
||||||
ddsrt_mutex_lock (&xevq->lock);
|
|
||||||
|
|
||||||
ASSERT_MUTEX_HELD (&xevq->lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_nontimed_xevent (struct xevent_nt *xev, struct nn_xpack *xp)
|
static void handle_nontimed_xevent (struct xevent_nt *xev, struct nn_xpack *xp)
|
||||||
|
@ -1635,6 +1640,7 @@ struct xevent *qxev_callback (struct xeventq *evq, nn_mtime_t tsched, void (*cb)
|
||||||
ev = qxev_common (evq, tsched, XEVK_CALLBACK);
|
ev = qxev_common (evq, tsched, XEVK_CALLBACK);
|
||||||
ev->u.callback.cb = cb;
|
ev->u.callback.cb = cb;
|
||||||
ev->u.callback.arg = arg;
|
ev->u.callback.arg = arg;
|
||||||
|
ev->u.callback.executing = false;
|
||||||
qxev_insert (ev);
|
qxev_insert (ev);
|
||||||
ddsrt_mutex_unlock (&evq->lock);
|
ddsrt_mutex_unlock (&evq->lock);
|
||||||
return ev;
|
return ev;
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
#include "dds/ddsi/q_config.h"
|
#include "dds/ddsi/q_config.h"
|
||||||
#include "dds/ddsi/q_entity.h"
|
#include "dds/ddsi/q_entity.h"
|
||||||
#include "dds/ddsi/q_globals.h"
|
#include "dds/ddsi/q_globals.h"
|
||||||
#include "dds/ddsi/q_ephash.h"
|
#include "dds/ddsi/ddsi_entity_index.h"
|
||||||
#include "dds/ddsi/q_freelist.h"
|
#include "dds/ddsi/q_freelist.h"
|
||||||
#include "dds/ddsi/ddsi_serdata_default.h"
|
#include "dds/ddsi/ddsi_serdata_default.h"
|
||||||
#include "dds/ddsi/ddsi_security_omg.h"
|
#include "dds/ddsi/ddsi_security_omg.h"
|
||||||
|
@ -724,7 +724,7 @@ void nn_xmsg_setdst1 (struct q_globals *gv, struct nn_xmsg *m, const ddsi_guid_p
|
||||||
guid.prefix = *gp;
|
guid.prefix = *gp;
|
||||||
guid.entityid.u = NN_ENTITYID_PARTICIPANT;
|
guid.entityid.u = NN_ENTITYID_PARTICIPANT;
|
||||||
|
|
||||||
proxypp = ephash_lookup_proxy_participant_guid(gv->guid_hash, &guid);
|
proxypp = entidx_lookup_proxy_participant_guid(gv->entity_index, &guid);
|
||||||
if (proxypp)
|
if (proxypp)
|
||||||
m->sec_info.dst_pp_handle = q_omg_security_get_remote_participant_handle(proxypp);
|
m->sec_info.dst_pp_handle = q_omg_security_get_remote_participant_handle(proxypp);
|
||||||
}
|
}
|
||||||
|
@ -859,7 +859,7 @@ int nn_xmsg_merge_rexmit_destinations_wrlock_held (struct q_globals *gv, struct
|
||||||
an addrset in rebuild_writer_addrset: then we don't
|
an addrset in rebuild_writer_addrset: then we don't
|
||||||
need the lock anymore, and the '_wrlock_held' suffix
|
need the lock anymore, and the '_wrlock_held' suffix
|
||||||
can go and everyone's life will become easier! */
|
can go and everyone's life will become easier! */
|
||||||
if ((wr = ephash_lookup_writer_guid (gv->guid_hash, &m->kindspecific.data.wrguid)) == NULL)
|
if ((wr = entidx_lookup_writer_guid (gv->entity_index, &m->kindspecific.data.wrguid)) == NULL)
|
||||||
{
|
{
|
||||||
GVTRACE ("writer-dead)");
|
GVTRACE ("writer-dead)");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1024,7 +1024,7 @@ static void nn_xmsg_chain_release (struct q_globals *gv, struct nn_xmsg_chain *c
|
||||||
struct writer *wr;
|
struct writer *wr;
|
||||||
assert (m->kindspecific.data.wrseq != 0);
|
assert (m->kindspecific.data.wrseq != 0);
|
||||||
wrguid = m->kindspecific.data.wrguid;
|
wrguid = m->kindspecific.data.wrguid;
|
||||||
if ((wr = ephash_lookup_writer_guid (gv->guid_hash, &m->kindspecific.data.wrguid)) != NULL)
|
if ((wr = entidx_lookup_writer_guid (gv->entity_index, &m->kindspecific.data.wrguid)) != NULL)
|
||||||
writer_update_seq_xmit (wr, m->kindspecific.data.wrseq);
|
writer_update_seq_xmit (wr, m->kindspecific.data.wrseq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,9 @@
|
||||||
#include "dds/ddsc/dds_rhc.h"
|
#include "dds/ddsc/dds_rhc.h"
|
||||||
#include "dds__rhc_default.h"
|
#include "dds__rhc_default.h"
|
||||||
#include "dds/ddsi/ddsi_iid.h"
|
#include "dds/ddsi/ddsi_iid.h"
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
#include "dds/ddsi/ddsi_lifespan.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "RhcTypes.h"
|
#include "RhcTypes.h"
|
||||||
|
|
||||||
|
@ -104,8 +107,20 @@ static struct ddsi_serdata *mkkeysample (int32_t keyval, unsigned statusinfo)
|
||||||
return sd;
|
return sd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t store (struct ddsi_tkmap *tkmap, struct dds_rhc *rhc, struct proxy_writer *wr, struct ddsi_serdata *sd, bool print)
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
static nn_mtime_t rand_texp ()
|
||||||
{
|
{
|
||||||
|
nn_mtime_t ret = now_mt();
|
||||||
|
ret.v -= DDS_MSECS(500) + (int64_t) (ddsrt_prng_random (&prng) % DDS_MSECS(1500));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static uint64_t store (struct ddsi_tkmap *tkmap, struct dds_rhc *rhc, struct proxy_writer *wr, struct ddsi_serdata *sd, bool print, bool lifespan_expiry)
|
||||||
|
{
|
||||||
|
#ifndef DDSI_INCLUDE_LIFESPAN
|
||||||
|
DDSRT_UNUSED_ARG (lifespan_expiry);
|
||||||
|
#endif
|
||||||
/* beware: unrefs sd */
|
/* beware: unrefs sd */
|
||||||
struct ddsi_tkmap_instance *tk;
|
struct ddsi_tkmap_instance *tk;
|
||||||
struct ddsi_writer_info pwr_info;
|
struct ddsi_writer_info pwr_info;
|
||||||
|
@ -132,6 +147,12 @@ static uint64_t store (struct ddsi_tkmap *tkmap, struct dds_rhc *rhc, struct pro
|
||||||
pwr_info.guid = wr->e.guid;
|
pwr_info.guid = wr->e.guid;
|
||||||
pwr_info.iid = wr->e.iid;
|
pwr_info.iid = wr->e.iid;
|
||||||
pwr_info.ownership_strength = wr->c.xqos->ownership_strength.value;
|
pwr_info.ownership_strength = wr->c.xqos->ownership_strength.value;
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
if (lifespan_expiry && (sd->statusinfo & (NN_STATUSINFO_UNREGISTER | NN_STATUSINFO_DISPOSE)) == 0)
|
||||||
|
pwr_info.lifespan_exp = rand_texp();
|
||||||
|
else
|
||||||
|
pwr_info.lifespan_exp = NN_MTIME_NEVER;
|
||||||
|
#endif
|
||||||
dds_rhc_store (rhc, &pwr_info, sd, tk);
|
dds_rhc_store (rhc, &pwr_info, sd, tk);
|
||||||
ddsi_tkmap_instance_unref (tkmap, tk);
|
ddsi_tkmap_instance_unref (tkmap, tk);
|
||||||
thread_state_asleep (lookup_thread_state ());
|
thread_state_asleep (lookup_thread_state ());
|
||||||
|
@ -651,7 +672,8 @@ static void test_conditions (dds_entity_t pp, dds_entity_t tp, const int count,
|
||||||
[8] = "rdc",
|
[8] = "rdc",
|
||||||
[9] = "tkc",
|
[9] = "tkc",
|
||||||
[10] = "tkc1",
|
[10] = "tkc1",
|
||||||
[11] = "delwr"
|
[11] = "delwr",
|
||||||
|
[12] = "drpxp"
|
||||||
};
|
};
|
||||||
static const uint32_t opfreqs[] = {
|
static const uint32_t opfreqs[] = {
|
||||||
[0] = 500, /* write */
|
[0] = 500, /* write */
|
||||||
|
@ -665,7 +687,12 @@ static void test_conditions (dds_entity_t pp, dds_entity_t tp, const int count,
|
||||||
[8] = 200, /* read cond */
|
[8] = 200, /* read cond */
|
||||||
[9] = 30, /* take cond */
|
[9] = 30, /* take cond */
|
||||||
[10] = 100, /* take cond, max 1 */
|
[10] = 100, /* take cond, max 1 */
|
||||||
[11] = 1 /* unreg writer */
|
[11] = 1, /* unreg writer */
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
[12] = 100 /* drop expired sample */
|
||||||
|
#else
|
||||||
|
[12] = 0 /* drop expired sample */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
uint32_t opthres[sizeof (opfreqs) / sizeof (opfreqs[0])];
|
uint32_t opthres[sizeof (opfreqs) / sizeof (opfreqs[0])];
|
||||||
{
|
{
|
||||||
|
@ -715,42 +742,42 @@ static void test_conditions (dds_entity_t pp, dds_entity_t tp, const int count,
|
||||||
case 0: { /* wr */
|
case 0: { /* wr */
|
||||||
struct ddsi_serdata *s = mksample (keyval, 0);
|
struct ddsi_serdata *s = mksample (keyval, 0);
|
||||||
for (size_t k = 0; k < nrd; k++)
|
for (size_t k = 0; k < nrd; k++)
|
||||||
store (tkmap, rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0);
|
store (tkmap, rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0, true);
|
||||||
ddsi_serdata_unref (s);
|
ddsi_serdata_unref (s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1: { /* wr disp */
|
case 1: { /* wr disp */
|
||||||
struct ddsi_serdata *s = mksample (keyval, NN_STATUSINFO_DISPOSE);
|
struct ddsi_serdata *s = mksample (keyval, NN_STATUSINFO_DISPOSE);
|
||||||
for (size_t k = 0; k < nrd; k++)
|
for (size_t k = 0; k < nrd; k++)
|
||||||
store (tkmap, rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0);
|
store (tkmap, rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0, true);
|
||||||
ddsi_serdata_unref (s);
|
ddsi_serdata_unref (s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: { /* disp */
|
case 2: { /* disp */
|
||||||
struct ddsi_serdata *s = mkkeysample (keyval, NN_STATUSINFO_DISPOSE);
|
struct ddsi_serdata *s = mkkeysample (keyval, NN_STATUSINFO_DISPOSE);
|
||||||
for (size_t k = 0; k < nrd; k++)
|
for (size_t k = 0; k < nrd; k++)
|
||||||
store (tkmap, rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0);
|
store (tkmap, rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0, true);
|
||||||
ddsi_serdata_unref (s);
|
ddsi_serdata_unref (s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 3: { /* unreg */
|
case 3: { /* unreg */
|
||||||
struct ddsi_serdata *s = mkkeysample (keyval, NN_STATUSINFO_UNREGISTER);
|
struct ddsi_serdata *s = mkkeysample (keyval, NN_STATUSINFO_UNREGISTER);
|
||||||
for (size_t k = 0; k < nrd; k++)
|
for (size_t k = 0; k < nrd; k++)
|
||||||
store (tkmap, rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0);
|
store (tkmap, rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0, true);
|
||||||
ddsi_serdata_unref (s);
|
ddsi_serdata_unref (s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 4: { /* disp unreg */
|
case 4: { /* disp unreg */
|
||||||
struct ddsi_serdata *s = mkkeysample (keyval, NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER);
|
struct ddsi_serdata *s = mkkeysample (keyval, NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER);
|
||||||
for (size_t k = 0; k < nrd; k++)
|
for (size_t k = 0; k < nrd; k++)
|
||||||
store (tkmap, rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0);
|
store (tkmap, rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0, true);
|
||||||
ddsi_serdata_unref (s);
|
ddsi_serdata_unref (s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 5: { /* wr disp unreg */
|
case 5: { /* wr disp unreg */
|
||||||
struct ddsi_serdata *s = mksample (keyval, NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER);
|
struct ddsi_serdata *s = mksample (keyval, NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER);
|
||||||
for (size_t k = 0; k < nrd; k++)
|
for (size_t k = 0; k < nrd; k++)
|
||||||
store (tkmap, rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0);
|
store (tkmap, rhc[k], wr[which], ddsi_serdata_ref (s), print && k == 0, true);
|
||||||
ddsi_serdata_unref (s);
|
ddsi_serdata_unref (s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -787,11 +814,24 @@ static void test_conditions (dds_entity_t pp, dds_entity_t tp, const int count,
|
||||||
wr_info.guid = wr[which]->e.guid;
|
wr_info.guid = wr[which]->e.guid;
|
||||||
wr_info.iid = wr[which]->e.iid;
|
wr_info.iid = wr[which]->e.iid;
|
||||||
wr_info.ownership_strength = wr[which]->c.xqos->ownership_strength.value;
|
wr_info.ownership_strength = wr[which]->c.xqos->ownership_strength.value;
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
wr_info.lifespan_exp = NN_MTIME_NEVER;
|
||||||
|
#endif
|
||||||
for (size_t k = 0; k < nrd; k++)
|
for (size_t k = 0; k < nrd; k++)
|
||||||
dds_rhc_unregister_wr (rhc[k], &wr_info);
|
dds_rhc_unregister_wr (rhc[k], &wr_info);
|
||||||
thread_state_asleep (lookup_thread_state ());
|
thread_state_asleep (lookup_thread_state ());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 12: {
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
thread_state_awake_domain_ok (lookup_thread_state ());
|
||||||
|
/* We can assume that rhc[k] is a dds_rhc_default at this point */
|
||||||
|
for (size_t k = 0; k < nrd; k++)
|
||||||
|
(void) dds_rhc_default_sample_expired_cb (rhc[k], rand_texp());
|
||||||
|
thread_state_asleep (lookup_thread_state ());
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((i % 200) == 0)
|
if ((i % 200) == 0)
|
||||||
|
@ -870,15 +910,15 @@ int main (int argc, char **argv)
|
||||||
struct dds_rhc *rhc = mkrhc (gv, NULL, DDS_HISTORY_KEEP_LAST, 1, DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP);
|
struct dds_rhc *rhc = mkrhc (gv, NULL, DDS_HISTORY_KEEP_LAST, 1, DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP);
|
||||||
struct proxy_writer *wr0 = mkwr (gv, 1);
|
struct proxy_writer *wr0 = mkwr (gv, 1);
|
||||||
uint64_t iid0, iid1, iid_t;
|
uint64_t iid0, iid1, iid_t;
|
||||||
iid0 = store (tkmap, rhc, wr0, mksample (0, 0), print);
|
iid0 = store (tkmap, rhc, wr0, mksample (0, 0), print, false);
|
||||||
iid1 = store (tkmap, rhc, wr0, mksample (1, NN_STATUSINFO_DISPOSE), print);
|
iid1 = store (tkmap, rhc, wr0, mksample (1, NN_STATUSINFO_DISPOSE), print, false);
|
||||||
const struct check c0[] = {
|
const struct check c0[] = {
|
||||||
{ "NNA", iid0, wr0->e.iid, 0,0, 1, 0,1 },
|
{ "NNA", iid0, wr0->e.iid, 0,0, 1, 0,1 },
|
||||||
{ "NND", iid1, wr0->e.iid, 0,0, 1, 1,2 },
|
{ "NND", iid1, wr0->e.iid, 0,0, 1, 1,2 },
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, 0 }
|
{ 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
rdall (rhc, c0, print, states_seen);
|
rdall (rhc, c0, print, states_seen);
|
||||||
iid_t = store (tkmap, rhc, wr0, mkkeysample (0, NN_STATUSINFO_UNREGISTER), print);
|
iid_t = store (tkmap, rhc, wr0, mkkeysample (0, NN_STATUSINFO_UNREGISTER), print, false);
|
||||||
assert (iid_t == iid0);
|
assert (iid_t == iid0);
|
||||||
(void)iid0;
|
(void)iid0;
|
||||||
(void)iid_t;
|
(void)iid_t;
|
||||||
|
@ -895,6 +935,9 @@ int main (int argc, char **argv)
|
||||||
wr0_info.guid = wr0->e.guid;
|
wr0_info.guid = wr0->e.guid;
|
||||||
wr0_info.iid = wr0->e.iid;
|
wr0_info.iid = wr0->e.iid;
|
||||||
wr0_info.ownership_strength = wr0->c.xqos->ownership_strength.value;
|
wr0_info.ownership_strength = wr0->c.xqos->ownership_strength.value;
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
|
wr0_info.lifespan_exp = NN_MTIME_NEVER;
|
||||||
|
#endif
|
||||||
dds_rhc_unregister_wr (rhc, &wr0_info);
|
dds_rhc_unregister_wr (rhc, &wr0_info);
|
||||||
thread_state_asleep (lookup_thread_state ());
|
thread_state_asleep (lookup_thread_state ());
|
||||||
const struct check c2[] = {
|
const struct check c2[] = {
|
||||||
|
@ -919,9 +962,9 @@ int main (int argc, char **argv)
|
||||||
struct proxy_writer *wr[] = { mkwr (gv, 0), mkwr (gv, 0), mkwr (gv, 0) };
|
struct proxy_writer *wr[] = { mkwr (gv, 0), mkwr (gv, 0), mkwr (gv, 0) };
|
||||||
uint64_t iid0, iid_t;
|
uint64_t iid0, iid_t;
|
||||||
int nregs = 3, isreg[] = { 1, 1, 1 };
|
int nregs = 3, isreg[] = { 1, 1, 1 };
|
||||||
iid0 = store (tkmap, rhc, wr[0], mksample (0, 0), print);
|
iid0 = store (tkmap, rhc, wr[0], mksample (0, 0), print, false);
|
||||||
iid_t = store (tkmap, rhc, wr[1], mksample (0, 0), print); assert (iid0 == iid_t);
|
iid_t = store (tkmap, rhc, wr[1], mksample (0, 0), print, false); assert (iid0 == iid_t);
|
||||||
iid_t = store (tkmap, rhc, wr[2], mksample (0, 0), print); assert (iid0 == iid_t);
|
iid_t = store (tkmap, rhc, wr[2], mksample (0, 0), print, false); assert (iid0 == iid_t);
|
||||||
(void)iid0;
|
(void)iid0;
|
||||||
tkall (rhc, NULL, print, states_seen);
|
tkall (rhc, NULL, print, states_seen);
|
||||||
for (int i = 0; i < 3*3 * 3*3 * 3*3 * 3*3; i++)
|
for (int i = 0; i < 3*3 * 3*3 * 3*3 * 3*3; i++)
|
||||||
|
@ -933,17 +976,17 @@ int main (int argc, char **argv)
|
||||||
switch (oper)
|
switch (oper)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
iid_t = store (tkmap, rhc, wr[which], mksample (0, 0), print);
|
iid_t = store (tkmap, rhc, wr[which], mksample (0, 0), print, false);
|
||||||
if (!isreg[which]) { nregs++; isreg[which] = 1; }
|
if (!isreg[which]) { nregs++; isreg[which] = 1; }
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
iid_t = store (tkmap, rhc, wr[which], mkkeysample (0, NN_STATUSINFO_DISPOSE), print);
|
iid_t = store (tkmap, rhc, wr[which], mkkeysample (0, NN_STATUSINFO_DISPOSE), print, false);
|
||||||
if (!isreg[which]) { nregs++; isreg[which] = 1; }
|
if (!isreg[which]) { nregs++; isreg[which] = 1; }
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (nregs > 1 || !isreg[which])
|
if (nregs > 1 || !isreg[which])
|
||||||
{
|
{
|
||||||
iid_t = store (tkmap, rhc, wr[which], mkkeysample (0, NN_STATUSINFO_UNREGISTER), print);
|
iid_t = store (tkmap, rhc, wr[which], mkkeysample (0, NN_STATUSINFO_UNREGISTER), print, false);
|
||||||
if (isreg[which]) { isreg[which] = 0; nregs--; }
|
if (isreg[which]) { isreg[which] = 0; nregs--; }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -958,7 +1001,7 @@ int main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
if (isreg[i])
|
if (isreg[i])
|
||||||
{
|
{
|
||||||
iid_t = store (tkmap, rhc, wr[i], mkkeysample (0, NN_STATUSINFO_UNREGISTER), print);
|
iid_t = store (tkmap, rhc, wr[i], mkkeysample (0, NN_STATUSINFO_UNREGISTER), print, false);
|
||||||
assert (iid_t == iid0);
|
assert (iid_t == iid0);
|
||||||
isreg[i] = 0;
|
isreg[i] = 0;
|
||||||
nregs--;
|
nregs--;
|
||||||
|
@ -967,10 +1010,10 @@ int main (int argc, char **argv)
|
||||||
assert (nregs == 0);
|
assert (nregs == 0);
|
||||||
tkall (rhc, 0, print, states_seen);
|
tkall (rhc, 0, print, states_seen);
|
||||||
wait_gc_cycle (gv->gcreq_queue);
|
wait_gc_cycle (gv->gcreq_queue);
|
||||||
iid_t = store (tkmap, rhc, wr[0], mksample (0, 0), print);
|
iid_t = store (tkmap, rhc, wr[0], mksample (0, 0), print, false);
|
||||||
assert (iid_t != iid0);
|
assert (iid_t != iid0);
|
||||||
iid0 = iid_t;
|
iid0 = iid_t;
|
||||||
iid_t = store (tkmap, rhc, wr[0], mkkeysample (0, NN_STATUSINFO_UNREGISTER), print);
|
iid_t = store (tkmap, rhc, wr[0], mkkeysample (0, NN_STATUSINFO_UNREGISTER), print, false);
|
||||||
assert (iid_t == iid0);
|
assert (iid_t == iid0);
|
||||||
frhc (rhc);
|
frhc (rhc);
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,11 @@ static void setqos (dds_qos_t *q, size_t i, bool isrd, bool create)
|
||||||
dds_qset_history (q, (dds_history_kind_t) ((i + 1) % 2), (int32_t) (i + 1));
|
dds_qset_history (q, (dds_history_kind_t) ((i + 1) % 2), (int32_t) (i + 1));
|
||||||
dds_qset_resource_limits (q, (int32_t) i + 3, (int32_t) i + 2, (int32_t) i + 1);
|
dds_qset_resource_limits (q, (int32_t) i + 3, (int32_t) i + 2, (int32_t) i + 1);
|
||||||
dds_qset_presentation (q, (dds_presentation_access_scope_kind_t) ((psi + 1) % 3), 1, 1);
|
dds_qset_presentation (q, (dds_presentation_access_scope_kind_t) ((psi + 1) % 3), 1, 1);
|
||||||
|
#ifdef DDSI_INCLUDE_LIFESPAN
|
||||||
dds_qset_lifespan (q, INT64_C (23456789012345678) + (int32_t) i);
|
dds_qset_lifespan (q, INT64_C (23456789012345678) + (int32_t) i);
|
||||||
|
#else
|
||||||
|
dds_qset_lifespan (q, DDS_INFINITY);
|
||||||
|
#endif
|
||||||
dds_qset_deadline (q, INT64_C (67890123456789012) + (int32_t) i);
|
dds_qset_deadline (q, INT64_C (67890123456789012) + (int32_t) i);
|
||||||
dds_qset_latency_budget (q, INT64_C (45678901234567890) + (int32_t) i);
|
dds_qset_latency_budget (q, INT64_C (45678901234567890) + (int32_t) i);
|
||||||
dds_qset_ownership (q, (dds_ownership_kind_t) ((i + 1) % 2));
|
dds_qset_ownership (q, (dds_ownership_kind_t) ((i + 1) % 2));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue