diff options
Diffstat (limited to 'src/cfgparse.c')
-rw-r--r-- | src/cfgparse.c | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/src/cfgparse.c b/src/cfgparse.c index ada344d17..173dcdb32 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -2566,8 +2566,54 @@ int check_config_validity() /* apply thread masks and groups to all receivers */ list_for_each_entry(li, &bind_conf->listeners, by_bind) { - li->rx.bind_thread = bind_conf->bind_thread; - li->rx.bind_tgroup = bind_conf->bind_tgroup; + if (bind_conf->settings.shards <= 1) { + li->rx.bind_thread = bind_conf->bind_thread; + li->rx.bind_tgroup = bind_conf->bind_tgroup; + } else { + struct listener *new_li; + int shard, shards, todo, done, bit; + ulong mask; + + shards = bind_conf->settings.shards; + todo = my_popcountl(bind_conf->bind_thread); + + /* no more shards than total threads */ + if (shards > todo) + shards = todo; + + shard = done = bit = 0; + new_li = li; + + while (1) { + mask = 0; + while (done < todo) { + /* enlarge mask to cover next bit of bind_thread */ + while (!(bind_conf->bind_thread & (1UL << bit))) + bit++; + mask |= (1UL << bit); + bit++; + done += shards; + } + + new_li->rx.bind_thread = bind_conf->bind_thread & mask; + new_li->rx.bind_tgroup = bind_conf->bind_tgroup; + done -= todo; + + shard++; + if (shard >= shards) + break; + + /* create another listener for new shards */ + new_li = clone_listener(li); + if (!new_li) { + ha_alert("Out of memory while trying to allocate extra listener for shard %d in %s %s\n", + shard, proxy_type_str(curproxy), curproxy->id); + cfgerr++; + err_code |= ERR_FATAL | ERR_ALERT; + goto out; + } + } + } } } |