/src/adhd/cras/server/cras_thread.c
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2024 The ChromiumOS Authors |
2 | | // Use of this source code is governed by a BSD-style license that can be |
3 | | // found in the LICENSE file. |
4 | | |
5 | | #include "cras/server/cras_thread.h" |
6 | | |
7 | | #include <pthread.h> |
8 | | #include <stdbool.h> |
9 | | #include <stdlib.h> |
10 | | #include <threads.h> |
11 | | |
12 | | #include "cras/common/check.h" |
13 | | |
14 | | static thread_local bool main_ctx_allowed = false; |
15 | | static thread_local bool audio_ctx_allowed = false; |
16 | | |
17 | | static struct cras_main_ctx mctx = {}; |
18 | | |
19 | 0 | struct cras_main_ctx* checked_main_ctx() { |
20 | 0 | CRAS_CHECK(main_ctx_allowed); |
21 | | |
22 | 0 | return &mctx; |
23 | 0 | } |
24 | | |
25 | 15.6k | struct cras_main_ctx* get_main_ctx_or_null() { |
26 | 15.6k | if (main_ctx_allowed) { |
27 | 15.6k | return &mctx; |
28 | 15.6k | } |
29 | 0 | return NULL; |
30 | 15.6k | } |
31 | | |
32 | | static struct cras_audio_ctx actx = {}; |
33 | | |
34 | 0 | struct cras_audio_ctx* checked_audio_ctx() { |
35 | 0 | CRAS_CHECK(audio_ctx_allowed); |
36 | | |
37 | 0 | return &actx; |
38 | 0 | } |
39 | | |
40 | 0 | struct cras_audio_ctx* get_audio_ctx_or_null() { |
41 | 0 | if (audio_ctx_allowed) { |
42 | 0 | return &actx; |
43 | 0 | } |
44 | 0 | return NULL; |
45 | 0 | } |
46 | | |
47 | 6 | __attribute__((constructor)) static void init() { |
48 | 6 | main_ctx_allowed = audio_ctx_allowed = true; |
49 | 6 | } |
50 | | |
51 | | struct start_routine_wrapper_data { |
52 | | void* (*start_routine)(void*); |
53 | | void* arg; |
54 | | }; |
55 | | |
56 | 6 | static void* start_routine_wrapper(void* arg) { |
57 | 6 | main_ctx_allowed = false; |
58 | 6 | audio_ctx_allowed = true; |
59 | 6 | struct start_routine_wrapper_data data = |
60 | 6 | *(struct start_routine_wrapper_data*)arg; |
61 | 6 | free(arg); |
62 | 6 | return data.start_routine(data.arg); |
63 | 6 | } |
64 | | |
65 | | int cras_thread_create_audio(pthread_t* thread, |
66 | | const pthread_attr_t* attr, |
67 | | void* (*start_routine)(void*), |
68 | 6 | void* arg) { |
69 | 6 | struct start_routine_wrapper_data* data = |
70 | 6 | calloc(sizeof(struct start_routine_wrapper_data), 1); |
71 | 6 | data->start_routine = start_routine; |
72 | 6 | data->arg = arg; |
73 | 6 | int rc = pthread_create(thread, attr, start_routine_wrapper, data); |
74 | | |
75 | 6 | if (rc != 0) { |
76 | 0 | free(data); |
77 | 0 | return rc; |
78 | 0 | } |
79 | | |
80 | | // Block accessing audio_ctx on the main thread if the audio thread was |
81 | | // created successfully. |
82 | 6 | audio_ctx_allowed = false; |
83 | 6 | return 0; |
84 | 6 | } |
85 | | |
86 | 0 | void cras_thread_disarm_checks() { |
87 | 0 | main_ctx_allowed = audio_ctx_allowed = true; |
88 | 0 | } |