Default to a single receive thread on Windows
This works around a termination issue on Windows caused by the process sometimes being unable to send a packet to itself to wake up a thread stuck in a blocking read on a socket. Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
parent
263d8016b8
commit
bb76798492
7 changed files with 75 additions and 34 deletions
|
@ -218,7 +218,7 @@ struct config
|
|||
int64_t liveliness_monitoring_interval;
|
||||
int prioritize_retransmit;
|
||||
int xpack_send_async;
|
||||
int multiple_recv_threads;
|
||||
enum boolean_default multiple_recv_threads;
|
||||
unsigned recv_thread_stop_maxretries;
|
||||
|
||||
unsigned primary_reorder_maxsamples;
|
||||
|
|
|
@ -149,9 +149,7 @@ DU(ipv4);
|
|||
DUPF(allow_multicast);
|
||||
DUPF(boolean);
|
||||
DU(boolean_default);
|
||||
#if 0
|
||||
PF(boolean_default);
|
||||
#endif
|
||||
DUPF(string);
|
||||
DU(tracingOutputFileName);
|
||||
DU(verbosity);
|
||||
|
@ -584,8 +582,8 @@ static const struct cfgelem unsupp_cfgelems[] = {
|
|||
BLURB("<p>This element controls whether the actual sending of packets occurs on the same thread that prepares them, or is done asynchronously by another thread.</p>") },
|
||||
{ LEAF_W_ATTRS("RediscoveryBlacklistDuration", rediscovery_blacklist_duration_attrs), 1, "10s", ABSOFF(prune_deleted_ppant.delay), 0, uf_duration_inf, 0, pf_duration,
|
||||
BLURB("<p>This element controls for how long a remote participant that was previously deleted will remain on a blacklist to prevent rediscovery, giving the software on a node time to perform any cleanup actions it needs to do. To some extent this delay is required internally by DDSI2E, but in the default configuration with the 'enforce' attribute set to false, DDSI2E will reallow rediscovery as soon as it has cleared its internal administration. Setting it to too small a value may result in the entry being pruned from the blacklist before DDSI2E is ready, it is therefore recommended to set it to at least several seconds.</p>") },
|
||||
{ LEAF_W_ATTRS("MultipleReceiveThreads", multiple_recv_threads_attrs), 1, "true", ABSOFF(multiple_recv_threads), 0, uf_boolean, 0, pf_boolean,
|
||||
BLURB("<p>This element controls whether all traffic is handled by a single receive thread or whether multiple receive threads may be used to improve latency. Currently multiple receive threads are only used for connectionless transport (e.g., UDP) and ManySocketsMode not set to single (the default).</p>") },
|
||||
{ LEAF_W_ATTRS("MultipleReceiveThreads", multiple_recv_threads_attrs), 1, "default", ABSOFF(multiple_recv_threads), 0, uf_boolean_default, 0, pf_boolean_default,
|
||||
BLURB("<p>This element controls whether all traffic is handled by a single receive thread (false) or whether multiple receive threads may be used to improve latency (true). By default it is disabled on Windows because it appears that one cannot count on being able to send packets to oneself, which is necessary to stop the thread during shutdown. Currently multiple receive threads are only used for connectionless transport (e.g., UDP) and ManySocketsMode not set to single (the default).</p>") },
|
||||
{ MGROUP("ControlTopic", control_topic_cfgelems, control_topic_cfgattrs), 1, 0, 0, 0, 0, 0, 0, 0,
|
||||
BLURB("<p>The ControlTopic element allows configured whether DDSI2E provides a special control interface via a predefined topic or not.<p>") },
|
||||
{ GROUP("Test", unsupp_test_cfgelems),
|
||||
|
@ -1456,7 +1454,7 @@ GENERIC_ENUM_CTYPE (boolean, int)
|
|||
|
||||
static const char *en_boolean_default_vs[] = { "default", "false", "true", NULL };
|
||||
static const enum boolean_default en_boolean_default_ms[] = { BOOLDEF_DEFAULT, BOOLDEF_FALSE, BOOLDEF_TRUE, 0 };
|
||||
GENERIC_ENUM_UF (boolean_default)
|
||||
GENERIC_ENUM (boolean_default)
|
||||
|
||||
static const char *en_besmode_vs[] = { "full", "writers", "minimal", NULL };
|
||||
static const enum besmode en_besmode_ms[] = { BESMODE_FULL, BESMODE_WRITERS, BESMODE_MINIMAL, 0 };
|
||||
|
|
|
@ -796,8 +796,36 @@ static void free_special_topics (struct q_globals *gv)
|
|||
ddsi_sertopic_unref (gv->rawcdr_topic);
|
||||
}
|
||||
|
||||
static bool use_multiple_receive_threads (const struct config *cfg)
|
||||
{
|
||||
/* Under some unknown circumstances Windows (at least Windows 10) exhibits
|
||||
the interesting behaviour of losing its ability to let us send packets
|
||||
to our own sockets. When that happens, dedicated receive threads can no
|
||||
longer be stopped and Cyclone hangs in shutdown. So until someone
|
||||
figures out why this happens, it is probably best have a different
|
||||
default on Windows. */
|
||||
#if _WIN32
|
||||
const bool def = false;
|
||||
#else
|
||||
const bool def = true;
|
||||
#endif
|
||||
switch (cfg->multiple_recv_threads)
|
||||
{
|
||||
case BOOLDEF_FALSE:
|
||||
return false;
|
||||
case BOOLDEF_TRUE:
|
||||
return true;
|
||||
case BOOLDEF_DEFAULT:
|
||||
return def;
|
||||
}
|
||||
assert (0);
|
||||
return false;
|
||||
}
|
||||
|
||||
static int setup_and_start_recv_threads (struct q_globals *gv)
|
||||
{
|
||||
const bool multi_recv_thr = use_multiple_receive_threads (&gv->config);
|
||||
|
||||
for (uint32_t i = 0; i < MAX_RECV_THREADS; i++)
|
||||
{
|
||||
gv->recv_threads[i].ts = NULL;
|
||||
|
@ -812,7 +840,7 @@ static int setup_and_start_recv_threads (struct q_globals *gv)
|
|||
gv->n_recv_threads = 1;
|
||||
gv->recv_threads[0].name = "recv";
|
||||
gv->recv_threads[0].arg.mode = RTM_MANY;
|
||||
if (gv->m_factory->m_connless && gv->config.many_sockets_mode != MSM_NO_UNICAST && gv->config.multiple_recv_threads)
|
||||
if (gv->m_factory->m_connless && gv->config.many_sockets_mode != MSM_NO_UNICAST && multi_recv_thr)
|
||||
{
|
||||
if (ddsi_is_mcaddr (gv, &gv->loc_default_mc) && !ddsi_is_ssm_mcaddr (gv, &gv->loc_default_mc) && (gv->config.allowMulticast & AMC_ASM))
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue