bankd: Implement thread-safe SIGUSR1 talloc context reporting
If the main thread receives SIGUSR1, we dump its talloc report and then signal all worker threads so each can dump their own talloc report. Change-Id: I89e7e22de5557376bd5a9625662d99ac0badf00c
This commit is contained in:
parent
286a2beaa9
commit
2507597c42
|
@ -61,6 +61,8 @@ struct bankd_worker {
|
||||||
|
|
||||||
/* thread of this worker. */
|
/* thread of this worker. */
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
|
/* top talloc context for this worker/thread */
|
||||||
|
void *tall_ctx;
|
||||||
|
|
||||||
/* File descriptor of the TCP connection to the remsim-client (modem) */
|
/* File descriptor of the TCP connection to the remsim-client (modem) */
|
||||||
struct {
|
struct {
|
||||||
|
@ -101,6 +103,9 @@ struct bankd {
|
||||||
/* list of slot mappings. only ever modified in main thread! */
|
/* list of slot mappings. only ever modified in main thread! */
|
||||||
struct slotmaps *slotmaps;
|
struct slotmaps *slotmaps;
|
||||||
|
|
||||||
|
/* pthread ID of main thread */
|
||||||
|
pthread_t main;
|
||||||
|
|
||||||
/* list of bankd_workers. accessed/modified by multiple threads; protected by mutex */
|
/* list of bankd_workers. accessed/modified by multiple threads; protected by mutex */
|
||||||
struct llist_head workers;
|
struct llist_head workers;
|
||||||
pthread_mutex_t workers_mutex;
|
pthread_mutex_t workers_mutex;
|
||||||
|
|
|
@ -56,10 +56,13 @@
|
||||||
|
|
||||||
/* signal indicates to worker thread that its map has been deleted */
|
/* signal indicates to worker thread that its map has been deleted */
|
||||||
#define SIGMAPDEL SIGRTMIN+1
|
#define SIGMAPDEL SIGRTMIN+1
|
||||||
|
|
||||||
|
static void handle_sig_usr1(int sig);
|
||||||
static void handle_sig_mapdel(int sig);
|
static void handle_sig_mapdel(int sig);
|
||||||
|
|
||||||
__thread void *talloc_asn1_ctx;
|
__thread void *talloc_asn1_ctx;
|
||||||
struct bankd *g_bankd;
|
struct bankd *g_bankd;
|
||||||
|
static void *g_tall_ctx;
|
||||||
|
|
||||||
static void *worker_main(void *arg);
|
static void *worker_main(void *arg);
|
||||||
|
|
||||||
|
@ -71,7 +74,7 @@ int asn_debug;
|
||||||
|
|
||||||
static void bankd_init(struct bankd *bankd)
|
static void bankd_init(struct bankd *bankd)
|
||||||
{
|
{
|
||||||
void *g_tall_ctx = talloc_named_const(NULL, 0, "global");
|
g_tall_ctx = talloc_named_const(NULL, 0, "global");
|
||||||
osmo_init_logging2(g_tall_ctx, &log_info);
|
osmo_init_logging2(g_tall_ctx, &log_info);
|
||||||
|
|
||||||
asn_debug = 0;
|
asn_debug = 0;
|
||||||
|
@ -241,7 +244,9 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
handle_options(argc, argv);
|
handle_options(argc, argv);
|
||||||
|
|
||||||
|
g_bankd->main = pthread_self();
|
||||||
signal(SIGMAPDEL, handle_sig_mapdel);
|
signal(SIGMAPDEL, handle_sig_mapdel);
|
||||||
|
signal(SIGUSR1, handle_sig_usr1);
|
||||||
|
|
||||||
/* Connection towards remsim-server */
|
/* Connection towards remsim-server */
|
||||||
rc = server_conn_fsm_alloc(g_bankd, srvc);
|
rc = server_conn_fsm_alloc(g_bankd, srvc);
|
||||||
|
@ -330,6 +335,29 @@ static void handle_sig_mapdel(int sig)
|
||||||
worker_set_state(g_worker, BW_ST_CONN_CLIENT_UNMAPPED);
|
worker_set_state(g_worker, BW_ST_CONN_CLIENT_UNMAPPED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_sig_usr1(int sig)
|
||||||
|
{
|
||||||
|
OSMO_ASSERT(sig == SIGUSR1);
|
||||||
|
|
||||||
|
if (pthread_equal(g_bankd->main, pthread_self())) {
|
||||||
|
struct bankd_worker *worker;
|
||||||
|
/* main thread */
|
||||||
|
fprintf(stderr, "=== Talloc Report of main thread:\n");
|
||||||
|
talloc_report(g_tall_ctx, stderr);
|
||||||
|
|
||||||
|
/* iterate over worker threads and ask them to dump their talloc state */
|
||||||
|
pthread_mutex_lock(&g_bankd->workers_mutex);
|
||||||
|
llist_for_each_entry(worker, &g_bankd->workers, list) {
|
||||||
|
pthread_kill(worker->thread, SIGUSR1);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&g_bankd->workers_mutex);
|
||||||
|
} else {
|
||||||
|
/* worker thread */
|
||||||
|
fprintf(stderr, "=== Talloc Report of %s\n", g_worker->name);
|
||||||
|
talloc_report(g_worker->tall_ctx, stderr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void worker_cleanup(void *arg)
|
static void worker_cleanup(void *arg)
|
||||||
{
|
{
|
||||||
struct bankd_worker *worker = (struct bankd_worker *) arg;
|
struct bankd_worker *worker = (struct bankd_worker *) arg;
|
||||||
|
@ -705,8 +733,8 @@ static void *worker_main(void *arg)
|
||||||
|
|
||||||
/* not permitted in multithreaded environment */
|
/* not permitted in multithreaded environment */
|
||||||
talloc_disable_null_tracking();
|
talloc_disable_null_tracking();
|
||||||
top_ctx = talloc_named_const(NULL, 0, "top");
|
g_worker->tall_ctx = talloc_named_const(NULL, 0, "top");
|
||||||
talloc_asn1_ctx = talloc_named_const(top_ctx, 0, "asn1");
|
talloc_asn1_ctx = talloc_named_const(g_worker->tall_ctx, 0, "asn1");
|
||||||
|
|
||||||
/* set the thread name */
|
/* set the thread name */
|
||||||
g_worker->name = talloc_asprintf(g_worker->tall_ctx, "bankd-worker(%u)", g_worker->num);
|
g_worker->name = talloc_asprintf(g_worker->tall_ctx, "bankd-worker(%u)", g_worker->num);
|
||||||
|
|
Loading…
Reference in New Issue